在Promise.all之前或之后调用

时间:2016-04-13 09:29:13

标签: javascript promise

目前我有以下代码:

var detailPromises = links.map(function (link) { return requestP(link) });

var oldPollNames = [];
// add a database call to the promises as it also can resolved during detail fetching
detailPromises.push(db.polls.findAsync({}, {title: 1}));
return Promise.all(detailPromises)
    .then(function (data) {
        oldPollNames = data.pop().map(function (item) { return item.title; });
        return data;
    })
    .then(function (htmls) {
        var newPolls = [];
        htmls.forEach(function (i, html) {
            // some processing of html using oldPollNames (newPools.push...)
        });
        return newPolls;
    })
    .then(/* insert into db */);

我正在做的是:等待db +等待html请求,然后处理booth。

我想知道这样做是否更有意义/更高效:

var detailPromises = links.map(function (link) { return requestP(link) });

return db.polls.findAsync({}, {title: 1}).then(function(polls) {
    var oldPollNames = polls.map(function (item) { return item.title; });
    var newPolls = [];

    detailPromises = detailPromises.map(function (p) {
        return p.then(function (html) {
            // some processing of html using oldPollNames (newPools.push...)
        })
    });

    return Promise.all(detailPromises)
        .done(function () {
            // insert newPolls into db
        });
});

第二种方法imo的优点是每个请求在完成后都已经(已经)处理过,并且可以在完成所有/其他承诺之前进行处理。

2 个答案:

答案 0 :(得分:2)

  

我想知道它是否会更有意义/更高效

是的,以更快的速度分别处理每个html请求,而不是等待所有这些请求,然后在一个巨大的循环中一起处理它们会更高效。它们不仅会更早地处理,还会避免可能长时间运行的繁重循环。

然而,该方法也有其缺点:实施起来更复杂。如果在数据库查询完成之前有任何Unhandled Rejection拒绝,或者其中任何一个拒绝并且数据库查询也被拒绝,那么您提供的代码很容易报告detailPromises。为了防止这种情况发生,您还需要对所有承诺使用Promise.all

var detailPromises = links.map(requestP);

var resultPromise = db.polls.findAsync({}, {title: 1}).then(function(polls) {
    var oldPollNames = polls.map(function(item) { return item.title; });
    var newPollPromises = detailPromises.map(function(p, i) {
        return p.then(function(html) {
            // some processing of html
        });
    });

    return Promise.all(newPollPromies) // not the detailPromises!
    .then(function(newPolls) {
        // insert newPolls into db
    });
});
return Promise.all([resultPromise].concat(detailPromises)).then(function(r) {
    return r[0];
});

答案 1 :(得分:0)

除了Bergi的回答,我想我找到了另一个同样的解决方案:

var detailPromises = links.map(requestP);
var pollNamePromise = db.polls.findAsync({}, {title: 1}).then(function(polls) {
        return polls.map(function (item) { return item.title; });
    });

var newPromises = detailPromises.map(function(p) {
        return Promise.join(p, pollNamePromise, function(html, oldPollNames) {
            // some processing of html using oldPollNames (newPools.push...)
        });
    });

Promise.all(newPromises).then(function(newPolls) {
    // insert newPolls into db
});

修改从Promise.all更改为Promise.join Bluebird