【问题标题】:Optimal way to chain Promise.all() with many calls many times多次调用多次链接 Promise.all() 的最佳方式
【发布时间】:2019-08-17 14:49:11
【问题描述】:

我正在开发一个 API 调用链,这些调用链通过调用带有 id 数组的 api、获取数据返回,然后在检索到一些数据的情况下对不同的端点进行下一次调用。

现在这完全是一个幼稚的解决方案 - 我希望获得一些关于如何最好地优化它的信息。我可能有大约 500 个数据点要处理。

apiHelper.apiCall(data, endpoint) 返回的是一组 promise,每次都在 Promise.all(); 中解析和管理 - 含义

目前它看起来像 6 个嵌套的 Promise.all() 相互之间的 .then():

Promise.all(function(){})
.then(function(){
    Promise.all(function(){})
    .then(function(){
        Promise.all(function(){})
        .then(function(){
            Promise.all(function(){})
            .then(function(){
            ...and so on...
            });
        });
    });
});

即半实数代码。

 var datapoints = req.body.toString().split("\n");
    var startingCount = datapoints.length;

    var preFailed = [];

    //initial naïve solution with nested Promise.all();
    var promises = apiHelper.apiCall(datapoints, endpoint + '?referenceId=');
    console.log('#INITIAL COUNT', promises.length);
    Promise
        .all(promises)
        .then(function (orderItems) {
            var itemHrefs = [];
            orderItems.forEach(function (oi) {
                if (oi.data.items && oi.data.items.length > 0) {
                    itemHrefs.push(oi.data.items[0].href); //get item href (has full order ref)
                }
            })

            //Find order items
            promises = apiHelper.apiCall(itemHrefs, '');
            Promise
                .all(promises)
                .then(function (retrievedOrders) {
                    var consumerOrderHrefs = [];
                    retrievedOrders.forEach(function (ro) {
                        if (ro.data.consumers) {
                            consumerOrderHrefs.push(ro.data.consumers.href); //get item href (has full order ref)
                        }
                    })


                    promises = apiHelper.apiCall(consumerOrderHrefs, '');
                    console.log('#STEP 3 FIND CONSUMERORDER COUNT', promises.length);
                    Promise
                        .all(promises)
                        .then(function (retrievedConsumers) {
                            var consumerHrefs = [];
                            retrievedConsumers.forEach(function (c) {
                                if (c.data.items[0]) {
                                    consumerHrefs.push(c.data.items[0].href); //get item href (has full order ref)
                                }
                            })

                            promises = apiHelper.apiCall(consumerHrefs, '');
                            console.log('#STEP 4 FIND CONSUMER COUNT', promises.length);
                            Promise
                                .all(promises)
                                .then(function (consumer) {
                                    var guestHrefs = [];
                                    consumer.forEach(function (c) {
                                        if (c.data.guest.href) {
                                            guestHrefs.push(c.data.guest.href); //get item href (has full order ref)
                                        }
                                    })

                                    promises = apiHelper.apiCall(guestHrefs, '');
                                    console.log('#STEP 5 GUEST COUNT', promises.length);
                                    Promise
                                        .all(promises)
                                        .then(function (guests) {
                                            var guest = [];
                                            guests.forEach(function (g) {
                                                if (g.data) {
                                                    guest.push(g.data); //get item href (has full order ref)
                                                }
                                            })
                                            res.status(200).json({guest});
                                        })
                                        .catch(function (err) {
                                            console.log('#ERR', err);
                                            res.status(500).send(err);
                                        });


                                })
                                .catch(function (err) {
                                    console.log('#ERR', err);
                                    res.status(500).send(err);
                                });
                        })
                        .catch(function (err) {
                            console.log('#ERR', err);
                            res.status(500).send(err);
                        });
                })
                .catch(function (err) {
                    console.log('#ERR', err);
                    res.status(500).send(err);
                });
        })
        .catch(function (err) {
            console.log('#ERR', err);
            res.status(500).send(err);
        });

【问题讨论】:

    标签: javascript node.js ecmascript-6 promise


    【解决方案1】:

    查看async/await

    const allPromises = async () => {
        await Promise.all(...);
        await Promise.all(...);
        //Etc.
    }
    

    【讨论】:

      【解决方案2】:

      您应该在此处应用的原则与任何其他承诺相同 - 在 then 中返回承诺并在下一个 then 中处理其结果:

      Promise.all(apiCall()) 
          .then(function (results) {
               var nextItems = // do something with results 
      
               return Promise.all(apiHelper.apiCall(nextItems, ''));
          })
          .then(function (results) {
               var nextItems = // do something with results 
      
               return Promise.all(apiHelper.apiCall(nextItems, ''));
          })
          .then(function (results) {
              // ...
          });
      

      【讨论】:

      • 啊,如果前面返回的是一组承诺,那么链接 .then() 就可以了。多么聪明
      • @mewc Promise.all 不返回一组承诺。它返回一个 Promise。
      • 更好。可以确认这行得通。谢谢 JLRishe
      【解决方案3】:

      这是另一种方式:

      var promise = Promise.all(...);
      promise = promise.then(() => Promise.all(...))
      promise = promise.then(() => Promise.all(...))
      promise = promise.then(() => Promise.all(...))
      promise = promise.then(() => Promise.all(...))
      promise.then(() => {
        console.log('all done!')
      })
      

      【讨论】:

      猜你喜欢
      • 2015-12-13
      • 1970-01-01
      • 2014-12-23
      • 2012-01-16
      • 2011-03-19
      • 1970-01-01
      • 2021-06-22
      • 1970-01-01
      • 2016-07-17
      相关资源
      最近更新 更多