Оптимальный способ связать Promise.all () с множеством вызовов много раз - PullRequest
1 голос
/ 27 марта 2019

Я разрабатываю цепочку API-вызовов, которые работают, делая вызовы 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 ]

2 голосов
/ 27 марта 2019

Принцип, который вы должны применять здесь, такой же, как и для любых других обещаний - вернуть обещание в пределах 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 голосов
/ 27 марта 2019

Просмотр async/await:

const allPromises = async () => {
    await Promise.all(...);
    await Promise.all(...);
    //Etc.
}
0 голосов
/ 27 марта 2019

Вот еще один способ:

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!')
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...