Javascript 在承诺之前或之后打电话
目前我有以下代码:Javascript 在承诺之前或之后打电话,javascript,promise,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}))
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第二种方法的优点是,每个请求在完成时(已经)得到处理,并且可以在所有/其他承诺实现之前完成其处理
我想知道这是否更有意义/更有效
是的,将每个html请求分开并尽可能快地处理会更高效,而不是等待所有请求,然后在一个巨大的循环中一起处理它们。不仅可以更早地处理它们,还可以避免可能长时间运行的繁重处理循环
然而,这种方法也有它的缺点:它的实现更加复杂。如果任何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];
});
除了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,可在您使用的Promise库中找到它?什么是.done
?您真的应该使用map
而不是forEach
和newPolls
数组。@Bergi您是对的,否则承诺。所有人都不会等待所有处理(newPools.push…)完成。Thx@Bergi“完成”是用在上的,但我实际上不知道他们为什么用它,萝拉,我明白了“请注意,promise.done(在本节示例中用作教学辅助工具)尚未标准化。”。你不应该使用它,总是选择然后
。Boarh我真的必须认真考虑它,但它是非常有意义的。有没有办法让它变得更好或者把东西放到函数中?我无法想象。@evelop:让哪一部分更好?我认为在蓝鸟中,你也可以做返回承诺。全部(细节承诺)。返回(结果承诺)
而不必担心未经处理的拒绝。如果我做以下事情,你认为这是过度工程吗: