如何让 promise.all 等待嵌套的 promise.all?

Ant*_*ony 4 javascript asynchronous promise es6-promise

所以我对 JavaScript Promises 有问题。我使用本机实现是为了减少依赖性。

我需要什么的说明性示例。

我需要检索书籍、书籍作者和购买的列表。我还需要每个作者的作者简介。在我得到所有这些之后,我需要创建一组漂亮的作者,他们的书和每本书的购买清单。

列表和配置文件是单独的 API JSON 调用。唯一的依赖是我需要一个作者列表才能获得作者简介。

我已经用 Promises 解决了这个问题。我使用 Promise.all 来获取 3 个 API JSON 请求:作者、书籍和购买。我使用另一个 Promise.all 来获取我获得的每个作者的所有个人资料(我遍历列表,为每个个人资料映射 url 并并行发送一批请求)。

我一获得作者列表就运行配置文件请求批处理,因此在作者列表承诺的“Then”处理程序中。

现在,问题:

为确保所有 Promise、3 个列表和所有配置文件都将在我组装库集之前完成,当我完成所有列表时,我需要在第一个 Promise.properties 中发送一批配置文件请求。所有 然后处理程序。

但是:购买的书籍列表比作者列表花费的时间要长得多,我不想等待所有这些都发送一批配置文件请求,所以我将它发送到作者列表承诺的 Then 处理程序中所以一旦我有了信息,这些就开始了。

但是,嵌套的 Promise.all 不计入其父 Promise.all Then 处理程序,因此由于我的 FinalFunction 位于顶级 Promise.all 的 Then 中,因此它可能(有时确实)在嵌套的 Promise.all 之前触发完成检索所有作者简介。

我需要能够尽快启动所有的 Promise 请求,但只有一批作者请求取决于一个 Promise 是否完成才能启动,所以我需要等待那个。所有其他的都应该独立开始。

伪代码

Promise.all(
  requestBooks().then(){},
  requestAuthors().then(){
    GenerateArrayOfAuthorUris();
    // now send a promisifyed batch of per-author requests
    Promise.all(
      [array of author uris to run requests for]
    )
    .then(){
      // If I run this here, I may not have upper-level requests done
      runCalculationsPerAuthorForAllAuthorsBooksPurchasesReceived();
    }
  },
  requestPurchases().then(){},
)
.then(){
  // this will fire when 3 top requests are done, but won't wait for 
  //   the nested Promise.all with per-author requests
  runCalculationsPerAuthorForAllAuthorsBooksPurchasesReceived();
}
Run Code Online (Sandbox Code Playgroud)

如果我这样做,我会浪费宝贵的时间来等待我不需要等待的请求来启动每个作者的请求:

Promise.all(
  requestBooks().then(){},
  requestAuthors().then(){
    GenerateArrayOfAuthorUris();
  },
  requestPurchases().then(){},
)
.then(){
    // now send a promisifyed batch of per-author requests
    Promise.all(
      [array of author uris to run requests for]
    )
    .then(){
      // If I run this here, I may not have upper-level requests done
      runCalculationsPerAuthorForAllAuthorsBooksPurchasesReceived();
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这能澄清我的需要。

谢谢你。

这是代码示例:https : //jsbin.com/qizohasofa/edit?js,console

Ber*_*rgi 5

正如您在评论中被告知的那样return,您的功能没有任何内容,因此then不知道要等待什么内部承诺。

function getJokeCategories() {
    return Promise.all([
//  ^^^^^^
        pgetJSON("http://api.icndb.com/categories"),
        pgetJSON("http://api.icndb.com/jokes/count").then(function(data) {
            var jokesToGet = [];
            for (var i=0; i<data; i++){
                jokesToGet.push("http://api.icndb.com/jokes/"+i);
            }
            return Promise.all(jokesToGet.map(function(jk) {
//          ^^^^^^
                return pgetJSON(jk).then(function(joke) {
//              ^^^^^^
                    console.log(jk + " just returned", joke);
                    return joke;
//                  ^^^^^^
                });
            })).then(function(jokes) {
                console.log("All jokes returned. This does happen only when all jokes are retrieved.");
                return {count:data, jokes:jokes};
//              ^^^^^^
            });
        })
    ]);
}
getJokeCategories().then(function(result) {
    console.log(result, "This does happen at the very end when joke count, joke categories and all jokes are returned.");
});
Run Code Online (Sandbox Code Playgroud)