【问题标题】:promise within promise with for loop带有 for 循环的 Promise 内的 Promise
【发布时间】:2018-02-06 07:35:37
【问题描述】:

我想调用多个 api,第二个 api 需要第一个 api 的东西,我创建了两个 promise,但现在我卡住了,我该如何执行需要完成的事情并等待它们全部完成?

createAccount(this.state.item) //promise
.then(resp=>{

  this.state.albums.forEach(o=>{ //array of object
    createAlbum(resp.id, { //promise
      ...o
    })
  })
})

我正在使用 bluebird 我得到了提示,使用 promise.all 但我不知道它如何与 forEach 一起使用,我无法控制那里有多少张专辑。

【问题讨论】:

  • 欢迎来到 Stack Overflow!请拿着tour,环顾四周,通读help center,尤其是How do I ask a good question?,您希望最外层promise 的分辨率值是多少? Promise.all 的文档不清楚?你尝试使用Promise.all 是什么样的?
  • docs中解释得很好
  • @OrB 但我不明白 :(

标签: javascript reactjs ecmascript-6 bluebird


【解决方案1】:

听起来您想创建帐户,然后创建一些存储在数组中的专辑。这确实正是Promise.all 的用途:

createAccount(this.state.item)
.then(resp =>
    Promise.all(
        this.state.albums.map(o => createAlbum(resp.id, o))
    )
);

您需要将then 创建的承诺返回给调用者,或者处理其上的错误(例如,通过.catch),就像承诺一样。

the bluebird docson MDN 中有关 Promise.all 的更多信息。

【讨论】:

  • 为什么 map 不是 foreach?我怎样才能得到 Promise.all 的响应?
  • @SharonChai:“为什么 map 不是 foreach?” 你有没有查看 map 的作用与 forEach 的作用? “我怎样才能得到 Promise.all 的响应?” 我建议通过一些关于 Promise 的教程来学习。上面Promise.all调用的结果就是上面then返回的promise的分辨率值。
【解决方案2】:

不清楚你想要什么,但如果你想处理每张专辑,你可以使用Promise.allArray.prototype.map 你的代码看起来像这样:

//if this is part of a function you shoud
// return createAccount ...
createAccount(this.state.item) //promise
.then(
  resp=>//arrow function without {} will return first statement
        //resp=>Promise.all(... is same as resp=>{ return Promise.all(...
    Promise.all(
      this.state.albums.map(
        album=>{
          //not sure why you want to keep calling createAlbum
          //  but only have one id, did you want to do album.id?
          createAlbum(resp.id)
          .then(
            o=>{
              //do something with o, album or response, they are all available
              return album;//you acn for example return album
            }
          )
        }
      )  
    )
)
.then(
  results=>{
    //results is an array of whatever o=> returns
  }
).catch(
  error=>{
    console.warn("something went wrong:",error);
  }
);

如果您有任何问题,请告诉我,可能需要:

  1. 您正在使用的代码
  2. 在代码中添加一些console.log("album is:",JSON.stringify(album,undefined,2) 语句(专辑就是一个例子)。因此,您可以自己调试一些代码,并确定您认为拥有的数据对象是否实际上是您拥有的对象。
  3. 您遇到的任何错误。在浏览器中按 F12 并查看控制台和网络选项卡。控制台将显示错误,您的 console.logs 和网络将向您的 xhr 显示错误/响应。

【讨论】:

  • 使用地图所以你能做到吗?为什么不 foreach?
  • @SharonChai forEach 不返回任何内容。它更适合于副作用,例如:“为每封电子邮件发送圣诞贺卡”而不是“为每个 url 给我一个在该 url 的内容中解析的承诺”这称为将 url 映射到响应的承诺。
【解决方案3】:

使用 promise.map 代替 promise.all,请在下面找到示例以供参考-

Promise.map(this.state.albums, function(fileName) {
    // Promise.map awaits for returned promises as well.
    return x;
}).then(function() {
    console.log("Done");
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2021-09-09
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 1970-01-01
    相关资源
    最近更新 更多