目前我有以下代码:
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的优点是每个请求在完成后都已经(已经)处理过,并且可以在完成所有/其他承诺之前进行处理。
答案 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