多次链接Promise.all()的最佳方法

时间:2019-03-27 05:30:59

标签: javascript node.js ecmascript-6 promise

我正在开发一连串的API调用,这些调用的工作方式是使用具有ID数组的api进行调用,获取数据的返回值,并使用已检索到的某些数据进行下一次调用。

现在,这完全是幼稚的解决方案-我希望就如何最佳地对此进行优化提供一些意见。在每个这些数据中,我可能要经过500个数据点。

apiHelper.apiCall(data, endpoint)返回的是一系列承诺,每次都会在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);
        });

3 个答案:

答案 0 :(得分:2)

查看async/await

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

答案 1 :(得分: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) {
        // ...
    });

答案 2 :(得分:0)

这是另一种方式:

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!')
})
相关问题