在承诺回调中发送数组响应,但响应为空白

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/awaitfor 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我的反应将是我想要的一样

以上是关于在承诺回调中发送数组响应,但响应为空白的主要内容,如果未能解决你的问题,请参考以下文章

使用 jquery 没有删除响应式 iframe 的空白

Google Adsense 响应式广告单元有时会在移动视图中产生空白

Yii2 - JSONP 响应不返回任何内容(空白)并且不起作用,但 JSON 可以

RSpec控制器测试 - 空白响应.body

在 Zapier 中处理列响应,其中一列是空白的

在 vc++ 代码中使用 wininet Api 发出 json 发布请求时得到空白响应