当某些调用工作而其他调用失败时,$ 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数组将填充数据。
当一个人失败时,我的理解是将调用第二个函数并给出错误变量详细信息。
但有人可以帮我解释一下,如果某些回复有效并且其他回复失败会发生什么?
答案 0 :(得分:39)
我相信,因为promise库基于Q
实现,所以一旦第一个promise被拒绝,就会调用拒绝回调并显示错误。它不等待其他承诺得到解决。请参阅Q
https://github.com/kriskowal/q的文档。对于Q.all,这就是提到的
all函数返回值数组的promise。当这个 承诺得到满足,数组包含了履行的值 原始承诺,与承诺的顺序相同。如果其中之一 如果承诺被拒绝,则返回的承诺立即生效 拒绝,而不是等待批次的其余部分。
答案 1 :(得分:38)
自问题发布以来已经有一段时间了,但也许我的回答可能仍然对某人有所帮助。我通过简单地解决所有承诺解决了类似的问题,但是我可以稍后处理返回并查看是否有任何错误。以下是我用于预加载某些图片资源的示例:
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
}
}
}
);
答案 2 :(得分:6)
编辑:仅在Kris Kowal的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;
}
});
});
答案 3 :(得分:5)
这是一个小答案。 如果在某些承诺中出现错误,你可以看到它是如何工作的。
$q.all([test1(), test2()]).then(function() {
// success
}, function() {
// error
});
答案 4 :(得分:4)
我找到了一个新的角度包,它将allSettled功能添加到$ q in angular:
答案 5 :(得分:1)
你能不能简单地处理$ http承诺的错误条件,然后再将它们传递给$ q?承诺被束缚,所以这应该有效:
return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData).then(function(r){return r;}, angular.noop);
显然,您可以将noop更改为您想要的任何转换,但这会阻止阻止$q.all
失败的拒绝。
答案 6 :(得分:0)
在我的情况下,无论成功还是失败,我都需要知道最后的承诺何时得到解决。 $ q.all不是一个选项,因为如果一个失败,它会立即下降。我需要这个以确保用户将被重定向,无论如何,但只有处理(或不处理)所有数据,以便可以在下一页加载它们。所以我最终得到了这个:
我知道这样做很蹩脚,但它对我有用。