在Promise.all之前或之后调用 [英] Calling then before or after Promise.all

查看:77
本文介绍了在Promise.all之前或之后调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我有以下代码:

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

var oldPollNames = [];
//添加对promises的数据库调用,因为它也可以在详细提取期间解析
detailPromises.push(db.polls.findAsync({},{title:1}));
返回Promise.all(detailPromises)
.then(function(data){
oldPollNames = data.pop()。map(function(item){return item.title;});
返回数据;
})
.then(函数(htmls){
var newPolls = [];
htmls.forEach(function(i,html){
//使用oldPollNames对某些html进行处理(newPools.push ...)
});
返回newPolls;
})
.then(/ * insert进入db * /);

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

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

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

返回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){
//使用oldPollNames对某些html进行处理(newPools.push ...)
})
});

返回Promise.all(detailPromises)
.done(function(){
//将newPolls插入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){
// html的一些处理
});
});

返回Promise.all(newPollPromies)//不是detailPromises!
.then(function(newPolls){
//将newPolls插入db
});
});
返回Promise.all([resultPromise] .concat(detailPromises))。then(function(r){
return r [0];
});


Currently I have following code:

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 */);

What I'm doing is: waiting for db + waiting for html requests and then process booth.

I'm wondering if it would make more sense / be more performant to do following:

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
        });
});

The advantage of the second approach imo is that each request gets (already) handled when it is done and can do it's procesing before all / other promises are fulfilled.

解决方案

I'm wondering if it would make more sense / be more performant

Yes, it would be more performant to process each html request separately and as fast as possible, instead of waiting for all of them and then processing them together in a huge loop. Not only will they processed earlier, you also avoid a possibly long-running loop of heavy processing.

However, the approach also has its drawbacks: it's more complicated to implement. The code you've given is prone to reporting Unhandled Rejections if any of the detailPromises rejects before the database query fulfills, or if any of them rejects and the database query is rejected as well. To prevent that, you'll need to use Promise.all on all the promises anyway:

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];
});

这篇关于在Promise.all之前或之后调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆