在承诺回调中发送数组响应,但响应为空白
Posted
技术标签:
【中文标题】在承诺回调中发送数组响应,但响应为空白【英文标题】:Sending array response in promise callback but the response is blank 【发布时间】:2019-11-07 12:48:57 【问题描述】:我正在从谷歌地图生成图像。这是一个承诺返回方法,因为我只是循环使用结果并将结果存储到“then”回调内的新数组变量中,但响应存在但它没有显示在浏览器中。
在我的谷歌地图生成图像功能不是承诺返回函数之前,它正在向浏览器发送响应,但它是一个承诺返回函数,因此响应存在但控制器方法没有向浏览器发送响应。
static providerMapImageGenerator(req, res)
let providerArr = []
ProvidersRepository.getProviderInfoForMapImage()
.then(providers =>
providers.forEach(provider =>
// Generating image against each entr
MapGenerator.getMapImage(
provider.latitude,
provider.longitude,
provider.name,
provider.providerId
)
.then(res =>
// Saving record after each entry
ProviderMap.create(
providerId: provider.providerId,
url: res.Location
)
// Adding new array for response
providerArr.push(
id: provider.providerId,
url: res.Location,
lat: provider.latitude,
long: provider.longitude,
name: provider.name
)
)
.catch(err => console.log(err, "err in generating image"))
)
// Sending final response against all generated entries to user
res.send(providerArr) // this is going blank to the browser
)
.catch(error =>
// Sending error response if fails
res.send(error)
)
我需要在浏览器中显示 providerArr 响应。
【问题讨论】:
For 循环在继续下一次迭代之前不会等待异步操作完成。使用Promise.all
并传递一组 promise 以等待它们全部完成
我该如何解决这个问题?
@IsaacVidrine 你能告诉我如何在我当前的代码中添加 promise.all。谢谢。
【参考方案1】:
您的循环无需等待承诺结果即可进行。您可以使用async/await
和for of
循环来执行您想要的操作,如下所示:
ProvidersRepository.getProviderInfoForMapImage()
.then(async (providers) =>
for(provider of providers)
// Generating image against each entr
let image = await MapGenerator.getMapImage(
provider.latitude,
provider.longitude,
provider.name,
provider.providerId
);
// Saving record after each entry
await ProviderMap.create(
providerId: provider.providerId,
url: res.Location
);
// Adding new array for response
providerArr.push(
id: provider.providerId,
url: res.Location,
lat: provider.latitude,
long: provider.longitude,
name: provider.name
);
)
// Sending final response against all generated entries to user
res.send(providerArr) // this is going blank to the browser
)
.catch(error =>
// Sending error response if fails
res.send(error)
)
PS:未测试
【讨论】:
for of 循环仅适用于对象,不适用于数组。所以这个解决方案对我不起作用。 但在将 for of 转换为 for 循环后它现在可以工作了。 @MuhammadAdil for...of 语句创建循环迭代可迭代对象,包括:内置字符串、数组、类数组对象(例如,参数或 NodeList)、TypedArray、Map、设置和用户定义的可迭代对象。它调用一个自定义迭代钩子,其中包含要为对象的每个不同属性的值执行的语句。这是文档:developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 你是对的。但我在我的代码中尝试了 for of 循环,但循环对我不起作用。不知道为什么,所以我尝试了 for 循环。 我的providers结果直接来自sequelize模型。也许它不是真正的类数组对象或可迭代对象。【参考方案2】:Amadou 的回答是正确的,但它按顺序而不是并行进行处理,等待每个 MapGenerator.getMapImage()
完成后再触发另一个请求。通过一些修改,您可以同时触发所有请求并等待所有请求完成。
static providerMapImageGenerator(req, res)
let providerArr = []
ProvidersRepository.getProviderInfoForMapImage()
.then(providers =>
return Promise.all(providers.map(provider =>
// Generating image against each entr
return MapGenerator.getMapImage( // ** actually return the promise so
provider.latitude, // ** Promise.all gets an array of promises
provider.longitude,
provider.name,
provider.providerId
)
.then(res =>
// Saving record after each entry
ProviderMap.create(
providerId: provider.providerId,
url: res.Location
)
// Adding new array for response
providerArr.push(
id: provider.providerId,
url: res.Location,
lat: provider.latitude,
long: provider.longitude,
name: provider.name
)
)
.catch(err => console.log(err, "err in generating image"))
)
// Sending final response against all generated entries to user
.then(() => res.send(providerArr)); // this is going blank to the browser
)
.catch(error =>
// Sending error response if fails
res.send(error)
)
【讨论】:
以上promise.all我的反应将是我想要的一样以上是关于在承诺回调中发送数组响应,但响应为空白的主要内容,如果未能解决你的问题,请参考以下文章
Google Adsense 响应式广告单元有时会在移动视图中产生空白