如何使promise.all等待嵌套的promise.all? [英] How to make promise.all wait for nested promise.all?

查看:124
本文介绍了如何使promise.all等待嵌套的promise.all?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I have a problem with JavaScript Promises. I'm using native implementation for the sake of reducing dependencies.

我需要的示例.

我需要检索书籍,书籍作者和购买的清单.我还需要每个作者的作者个人资料.掌握了所有这些内容之后,我需要创建一组不错的作者,包括他们的书和每本书的购买清单.

I need to retrieve lists of books, book authors and purchases. I also need an author profile for each of the authors. After I got all of that, I need to create a nice set of Authors with their books and purchase list for each of the books.

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

Lists and profiles are separate API JSON calls. The only dependency is that I need a list of authors to be able to get author profiles.

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

I've solved this with Promises. I use Promise.all to get 3 API JSON requests for: authors, books and purchases. I use yet another Promise.all to get all the profiles for each of the authors I get (I loop through the list, map urls for each profile and send a batch of requests in parallel).

我一获得作者列表便立即运行概要文件请求批处理,因此在作者列表promise的"Then"处理程序中.

I run the profile request batch as soon as I get the list of authors, thus in the "Then" handler of the author list promise.

现在,问题所在:

为确保所有诺言,3个列表和所有概要文件都将在组装库集之前完成,当我用完所有列表后,我将需要发送一批概要文件请求.首先是Promise.all,然后是处理程序.

To be sure that all promises, 3 lists and all profiles, will be done prior to my assembling of the library set, I would need to send a profile batch of requests when I'm done with all the lists, in the first Promise.all Then handler.

但是:购买的图书清单比作者清单要花费更长的时间,我不想等待所有这些人发送一批配置文件请求,因此我将其发送到作者的Then处理程序中-list许诺,以便这些在我掌握信息后立即开始.

But: lists of books an purchases take much longer time than the list of authors and I don't want to wait for all of those to send a batch of profile requests, so I send it in the Then handler of the author-list promise so these start as soon as I have the info.

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

However, a nested Promise.all does not count towards its parent Promise.all Then handler so since my FinalFunction is in the Then of the top-level Promise.all, it may (and sometimes does) fire before the nested Promise.all has finished retrieving all author profiles.

我需要能够尽快启动所有Promise请求,但是只有一小部分作者请求取决于一个诺言是否完整才能启动,因此我需要等待一个诺言.所有其他都应该独立启动.

I need to be able to start all of the Promise requests as soon as possible, but only the batch of author requests depends on one promise being complete to start, so I need to wait on that one. All other should start independently.

伪代码

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();
}

如果我这样做,那是在浪费宝贵的时间,因为我只需要等待每个作者请求即可,而不必等待:

If I do it this way, I'm wasting precious time by waiting for requests I don't need to wait on just to start per-author requests:

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();
    }
}

希望这可以澄清我的需求.

Hopefully this clarifies what I need.

谢谢.

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

推荐答案

正如您在注释中告诉您的那样,您没有返回函数中的任何内容,因此然后>不知道内心的承诺要等什么.

As you were told in the comments, you didn't return anything from your functions, so then didn't know what inner promises to wait for.

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.");
});

这篇关于如何使promise.all等待嵌套的promise.all?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆