当一些调用工作而另一些调用失败时,$ q.all()会发生什么?

当一些调用工作而另一些调用失败时,$ 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数组充满数据。

当一个失败,这是我的理解,第二个函数将被调用和错误variables给出的细节。

然而,有人可以帮我解释一下,如果一些反应有效而其他反应失败会发生什么?

我相信既然promise库基于Q实现,只要第一个promise被拒绝,拒绝callback就会被调用。 它不等待其他的承诺解决。 请参阅Q文档https://github.com/kriskowal/q 。 对于Q.all,这是提到的

全部函数返回一个值数组的承诺。 当这个承诺被履行时,这个数组包含原始承诺的履行价值,与承诺的顺序相同。 如果某个给定的承诺被拒绝,则返回的承诺立即被拒绝,而不是等待批处理的其余部分。

这个问题已经发布了一段时间了,但也许我的答案可能仍然有帮助。 我解决了一个类似的问题,只是简单地解决了所有的承诺,但后来我可以处理,看看是否有任何错误。 以下是我的示例,用于预加载一些图像资源:

 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 – 支持,但仍然是一个有用的珍闻

如果你想在不拒绝的情况下全部处理它们,请使用allSettled

以下是文档的说明:

如果你想等待所有的承诺被履行或拒绝,你可以使用allSettled。

 Q.allSettled(promises) .then(function (results) { results.forEach(function (result) { if (result.state === "fulfilled") { var value = result.value; } else { var reason = result.reason; } }); }); 

这是一个小的答案。 在这个小提琴中,你可以看到它是如何工作的,如果在某些承诺中出现错误。

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

http://jsfiddle.net/wd9w0ja4/

我find了一个新的angular度包,它将allSettled的function添加到$ qangular度:

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

在我的情况下,我需要知道什么时候最后的承诺已经解决,不pipe成功或失败。 $ q.all不是一个选项,因为如果一个失败,它立即下降。 我需要这样做,以确保用户将被redirect,无论如何,但只有所有的数据处理(或不),所以他们可以在下一页加载。 所以我结束了这个:

  1. 在成功和失败callback中都调用“redirect”function的情况下,实现的每个承诺/调用也都会失败。
  2. 在这个函数中计数器被设置,每次调用都会增加。 如果达到承诺/呼叫次数,则redirect到下一个视图。

我知道这是一个很蹩脚的方式,但它对我有用。

你能不能简单地处理你的$ http promises的错误条件,然后把它们传递给$ q? 承诺链接,所以这应该工作:

 return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData).then(function(r){return r;}, angular.noop); 

显然,你可以改变noop到任何你想要的转换,但这可以防止拒绝,防止$q.all失败。