【问题标题】:Add promise to $q.all()向 $q.all() 添加承诺
【发布时间】:2016-09-09 17:46:50
【问题描述】:

在执行一些代码(angularJS)之前,我需要等待几个承诺完成:

var promises = [calculationPromise1, calculationPromise2];
$q.all(promises)
   .then(function(){
        notifyUser("I am done calculating!");
    });

在我的例子中,用户可以随时添加新的计算。所以如果他增加一个新的计算,通知应该被进一步延迟。

修改初始数组

遗憾的是$q.all 不会监听 promise-array 上的更改,因此执行此操作没有任何效果:

promises.push(newCalc);

创建一个新的 $q.all-promise

这也不起作用,因为通知将显示多次而不是延迟:

var promises = [calculationPromise1, calculationPromise2];
var qAllPromise; 

qAllPromise = $q.all(promises)
   .then(function(){
         notifyUser("I am done calculating!");
    })

function addAnotherCalculation(calc){
   qAllPromise = $q.all([calc, qAllPromise])
     .then(function(){
         notifyUser("I am done calculating!");
     })
}    

递归调用

递归调用 $q.all 并只执行一次 .then 块应该可以工作:

var promises = [calculationPromise1, calculationPromise2];

function notifyWhenDone() {
$q.all(promises)
   .then(function() {
      if(allPromisesResolved()){
          notifyUser("I am done calculating!");
      }
      else {
          notifyWhenDone();
      }
    })
}

function addAnotherCalculation(calc){
   promises.push(calc);
}

我的问题是 Angular 没有提供 API 来检查我在 allPromisesResolved 函数中需要的承诺状态。我可以检查 promise.$$state.status === 1 来识别已解决的承诺,但如果我不需要,我宁愿不使用内部变量 ($$state)。

问题

有没有一种简单的方法可以将 Promise 添加到 $q.all Promise 中,或者您能想出一种替代解决方案来等待动态增长的 Promise 数量吗?

【问题讨论】:

  • allPromisesResolved 没有意义,因为如果你在 then 回调中,所有的承诺都会按照定义解决。我认为对于您要实现的目标而言,承诺是错误的模式。
  • 我真的无法选择是否使用 Promise,因为它们是处理异步调用的工具。然而,使用$q.all 的选择是有争议的——我觉得它很直观。
  • 澄清一下:方法allPromisesResolved 的目的是检查是否实际上所有当前相关的承诺都已解决。这与导致then 执行的条件不同,因为可能在调用$q.all 之后和执行.then 之前添加了新的承诺/计算。
  • 如果用户在 allPromisesResolved 已经实现后添加另一个承诺,你希望发生什么?
  • 然后看看this answer

标签: javascript angularjs promise angular-promise


【解决方案1】:

您可以通过递归来完成此操作。您可以在每次调用 $q.all() 时清空您的 Promise 数组,然后在到达 then() 处理程序时检查它是否有任何新值:

var promises = [calculationPromise1, calculationPromise2];

function waitForPromises(completedSoFar) {
    var p = $q
        .all((completedSoFar || []).concat(promises))
        .then(function (results) {
             return promises.length
                 ? waitForPromises(results)
                 : results;
        });

    promises = [];

    return p;
}

waitForPromises().then(function (results) {
    // all done
});

【讨论】:

    猜你喜欢
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    相关资源
    最近更新 更多