Promise.all 在同一个数组上

Promise.all on same array

我正在查看执行以下操作的基于承诺的代码:

var promises = [];
function eventHandler(e)
{
    promises.push(getSomeData(e.opts));

    Promise.all(promises)
        .then(...)
        .then(function()
        {
            promises = [];
        });
}

基于 Promise.all 的 promise 的执行次数不应该与调用 eventHandler 的次数一样多吗?

编辑:这里发生的事情是事件处理程序被调用了几次,之前的承诺还没有完成。我需要一种方法来扩展承诺列表并且只有一个最终的 then 运行.

更新,OP 已澄清他们希望在原始承诺解决之前等待所有添加的承诺 -.all 不这样做。相反,您可以使用 thenable 链接。

var p = Promise.resolve([]); // create empty array promise, `when` in dojo
function eventHandler(e){
    p = p.then(function(value){ // chain off the last value
        return getSomeData(e.opts).then(function(single){
            return value.push(single); // add to the array
        });
    });
}

这将在每次调用 eventHandler 时向数组添加一个项目 - 每次您 .then 您将获得 current 值而不是最后一个值- 但您可以 .then 多次。例如,您可以在自链接时间以来没有事件发生时链接:

var p2 == p;
p.then(function(results){
    if(p !== p2) return p; // wait in case more events happened, but no more
    return results;
});

或者等多久都行:

function noMoreAddedInterim(){
   var p2 = p;
   return p.then(function(results){
       if(p2 !== p) return noMoreAddedInterim(); // changed
       else return results; // no more added
   });
 }

你有一个竞争条件,你正在调用 Promise.all 并且只在稍后清理数组所以很多承诺在结果中出现两次或更多次。

而是 - 将 promises 放入一个临时变量中,.all 并清除 .then 之前的 promises。由于您一次添加一个承诺,因此您可能甚至不需要此处的 .all

此外,您应该附加一个 .catch 处理程序,以免遗漏任何错误。