当某些调用有效而其他调用失败时 $q.all() 会发生什么?

IT技术 javascript angularjs angular-promise
2021-02-22 23:53:27

当某些调用有效而其他调用失败时 $q.all() 会发生什么?

我有以下代码:

    var entityIdColumn = $scope.entityType.toLowerCase() + 'Id';
    var requests = $scope.grid.data
      .filter(function (rowData, i) {
          return !angular.equals(rowData, $scope.grid.backup[i]);
      })
      .map(function (rowData, i) {
          var entityId = rowData[entityIdColumn];
          return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData);
      });
    $q.all(requests).then(function (allResponses) {
        //if all the requests succeeded, this will be called, and $q.all will get an
        //array of all their responses.
        console.log(allResponses[0].data);
    }, function (error) {
        //This will be called if $q.all finds any of the requests erroring.
        var abc = error;
        var def = 99;
    });

当所有 $http 调用工作时,allResponses 数组将填充数据。

当一个失败时,我的理解是将调用第二个函数并给出错误变量的详细信息。

但是,有人可以帮助我解释如果某些响应有效而其他响应失败会发生什么吗?

6个回答

我相信由于 promise 库是基于Q实现的,一旦第一个 promise 被拒绝,就会调用拒绝回调并显示错误。它不会等待其他Promise得到解决。请参阅Q https://github.com/kriskowal/q 的文档对于 Q.all 这就是所提到的

all 函数返回一个值数组的Promise。当这个Promise被履行时,数组包含原始Promise的履行值,与那些Promise的顺序相同。如果给定的Promise之一被拒绝,则返回的Promise会立即被拒绝,而不是等待批次的其余部分。

我想这对我来说可能是个问题。我的 put 请求返回带有新行版本号的数据。如果该数据不可用,那么下次我尝试进行更新时,该更新可能会失败:-( 有什么办法可以让我想到如何解决这个问题?
2021-04-28 23:53:27
阅读此处的文档docs.angularjs.org/api/ng.$q看看finally能不能帮到你。也许您需要将Promise分成几组。
2021-05-01 23:53:27

这个问题发布已经有一段时间了,但也许我的回答可能仍然对某人有所帮助。我通过简单地解决所有Promise解决了类似的问题,但是我可以稍后处理并查看是否有任何错误。这是我用于预加载一些图像资产的示例:

var loadImg = function(imageSrc) {
    var deferred = $q.defer();

    var img = new Image();
    img.onload = function() {
        deferred.resolve({
            success: true,
            imgUrl: imageSrc
        });
    };
    img.onerror = img.onabort = function() {
        deferred.resolve({
            success: false,
            imgUrl: imageSrc
        });
    };
    img.src = imageSrc;

    return deferred.promise;
}

后来我可以看到哪些是错误的:

var promiseList = [];
for (var i = 0; i < myImageList.length; i++) {
    promiseList[i] = loadImg(myImageList[i]);
}
$q.all(promiseList).then(
    function(results) {
        for (var i = 0; i < results.length; i++) {
            if (!results[i].success) {
                // these are errors
            }
        }
    }
);
好主意!一般解释:这里的方法是在另一个临时异步函数后面运行异步函数(可能会解析/拒绝并且您想要它们全部),该函数仅“解析”并为它们使用 $q.all,而不是原始的异步函数。
2021-04-21 23:53:27
应该是“错误的”,但在将近 5 年后不会纠正自己:D
2021-05-05 23:53:27
真的是一个不错的。:)
2021-05-18 23:53:27

编辑:仅在 Kris Kowal 的 Q 中支持 - 但仍然是一个有用的花絮

如果您想处理所有这些而不在失败时立即拒绝,请使用 allSettled

这是文档所说的:

如果您想等待所有Promise被履行或被拒绝,您可以使用 allSettled。

Q.allSettled(promises)
.then(function (results) {
    results.forEach(function (result) {
        if (result.state === "fulfilled") {
            var value = result.value;
        } else {
            var reason = result.reason;
        }
    });
});
allSettledkriskowal 的 Q 的一部分,但不是 Angular $q 实现的一部分。
2021-04-23 23:53:27

这是一个小答案。在这个小提琴中,您可以看到它是如何工作的,如果某个Promise发生错误。

$q.all([test1(), test2()]).then(function() {
  // success
}, function() {
  // error
});

http://jsfiddle.net/wd9w0ja4/

小提琴是思考 $q.all 的好方法
2021-05-15 23:53:27

我发现了一个新的 angular 包,它在 angular 中将 allSettled 功能添加到 $q 中:

https://github.com/ohjames/angular-promise-extras