【问题标题】:Angular $q.all() not waiting for all promisesAngular $q.all() 不等待所有承诺
【发布时间】:2016-11-03 23:06:03
【问题描述】:

我有这个代码:

var promiseArr = [],
    innerPromises = [],
    innerIndex = 0;

angular.forEach(some_object, function (value, key) {
    console.log(1);
    innerPromises[innerIndex] = $q.defer();
    promiseArr.push(innerPromises[innerIndex].promise);
    (function(innerIndex) {
        func_returning_promise(args).then(function(data) {
            console.log(2);
            // Some code working on returned data
            innerPromises[innerIndex].resolve(true);
        });
    })(innerIndex);

    innerIndex++;
});

$q.all(promiseArr).then(function() {
    console.log(3);
});

forEach 运行 3 次。预期的结果是

1
1
1
2
2
2
3

但是3 出现在2s 之前和1s 之后,这对我来说似乎完全不合逻辑! innerPromises 无法解析,但在 2s 被记录后。

感谢您的帮助。

【问题讨论】:

  • 不是我的答案的一部分,所以我将作为评论添加:您不必明确创建内部承诺。 func_returning_promise(args).then(...) 返回一个 Promise,因此您只需将其推送到您的 Promise 数组中,当成功函数完成时,它将自动为您解析或拒绝。

标签: angularjs promise angular-promise


【解决方案1】:

您的代码似乎不完整,无论如何经过一些调整后,我能够使您的代码在 jsfiddle 上运行。 https://jsfiddle.net/yw6qztxm/

angular.module('indexApp', []).controller('indexController', function($q,   $timeout) {

var promiseArr = [],
    innerPromises = [],
    innerIndex = 0;

var some_object = { 1:1, 2:2, 3:3 }
var args = false;

function func_returning_promise() {
  return $q(function(resolve) {
    $timeout(resolve, 100 + 100 * innerIndex);
  });
}

angular.forEach(some_object, function (value, key) {
    console.log(1);
    innerPromises[innerIndex] = $q.defer();
    promiseArr.push(innerPromises[innerIndex].promise);
    (function(innerIndex) {
        func_returning_promise(args).then(function(data) {
            console.log(2);
            // Some code working on returned data
            innerPromises[innerIndex].resolve(true);
        });
    })(innerIndex);

    innerIndex++;
});

$q.all(promiseArr).then(function() {
    console.log(3);
});

});

它符合预期,因为最后记录了 3,也许你应该用缺少的函数和变量做一个工作示例。

【讨论】:

    【解决方案2】:

    我的猜测是,在提取代码而不是发布完整示例时,您已经改变了行为。 forEach() 很可能在您的原始版本中也在异步回调中,这意味着 $q.all() 在一个空列表上运行并立即解析。

    所以我建议的顺序是:

    1. 你做了一些未显示的事情,它立即解决了一个承诺 A。
    2. $q.all() 在一个空列表上运行,因此它返回的承诺 B 解决。
    3. Angular 运行 promise A 的成功函数,该函数运行 forEach 循环并打印您所有的 1 并将承诺附加到 数组。
    4. 然后它运行 promise B 的成功函数,该函数打印 3
    5. 然后其他承诺完成并打印2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      • 2017-04-04
      • 2014-03-12
      相关资源
      最近更新 更多