[英]Handling errors in multiple calls of AngularJS promises
I have an AngularJS service with such async API: 我有一个带有这种异步API的AngularJS服务:
myService.asyncCall(['id0', 'id3', 'id2']).then(function (complexData) {
// handle complexData
}).catch(function (error) {
console.log(error);
});
asyncCall
incapsulates multiple calls of $http
which handled by $q.all
. asyncCall
封装由$q.all
处理的多个$http
调用。 Each of the $http
requests can response with error and I want the errors to be handled by one catch
handler. 每个$http
请求都可以响应错误,我希望错误由一个catch
处理程序处理。 So how i can achieve multiple calls of the catch
handler ? 那我怎么能实现catch
处理程序的多次调用呢?
If I understood correctly (finally), this is what you are trying to achieve: 如果我理解正确(最后),这就是你想要实现的目标:
$q.all
should be "augmented" to suit your needs, because by default: $q.all
应该“增强”以满足您的需求,因为默认情况下:
Here is a possible implementation: 这是一个可能的实现:
function asyncCall(listOfPromises, onErrorCallback, finalCallback) {
listOfPromises = listOfPromises || [];
onErrorCallback = onErrorCallback || angular.noop;
finalCallback = finalCallback || angular.noop;
// Create a new list of promises that can "recover" from rejection
var newListOfPromises = listOfPromises.map(function (promise) {
return promise.catch(function (reason) {
// First call the `onErrroCallback`
onErrorCallback(reason);
// Change the returned value to indicate that it was rejected
// Based on the type of `reason` you might need to change this
// (e.g. if `reason` is an object, add a `rejected` property)
return 'rejected:' + reason;
});
});
// Finally, we create a "collective" promise that calls `finalCallback` when resolved.
// Thanks to our modifications, it will never get rejected !
$q.all(newListOfPromises).then(finalCallback);
}
See, also, this short demo . 另见这个简短的演示 。
One way, would be to attach a .catch
handler indidually in your service: 一种方法是在您的服务中单独附加.catch
处理程序:
function asyncCall(urls){
var calls = urls.map(makeSomeCall).
map(function(prom){ return prom.catch(e){ /* recover here */});
return $q.all(calls);
};
Another way would be to implement a settle
method that is like $q.all
but keeps track of all results. 另一种方法是实现类似$q.all
的settle
方法,但跟踪所有结果。 Stealing from my answer here : 从我的回答窃取这里 :
function settle(promises){
var d = $q.defer();
var counter = 0;
var results = Array(promises.length);
promises.forEach(function(p,i){
p.then(function(v){ // add as fulfilled
results[i] = {state:"fulfilled", promise : p, value: v};
}).catch(function(r){ // add as rejected
results[i] = {state:"rejected", promise : p, reason: r};
}).finally(function(){ // when any promises resolved or failed
counter++; // notify the counter
if (counter === promises.length) {
d.resolve(results); // resolve the deferred.
}
});
});
})
You can handle multiple promises as such: 您可以处理多个承诺:
var promiseArr = ["id0","id3","id2"].map(makePromise);
settle(promiseArr).then(function(results){
var failed = results.filter(function(r){ return r.state === "rejected"; });
var failedValues = failed.map(function(i){ return i.value; });
var done = results.filter(function(r){ return r.state === "fulfilled"; });
var doneValues = done.map(function(i){ return i.value; });
});
Which gives you access to all results of the promise, regardless if it failed or not, and let you recover with more granularity. 这使您可以访问承诺的所有结果,无论它是否失败,并让您以更细的粒度进行恢复。
Your service should handle that aggregation since it's the one returning a promise on everything. 您的服务应该处理该聚合,因为它是对所有内容返回承诺的聚合。 One example would be to do: 一个例子是:
if(failed.length > 0){
throw new Error("The following failed..."); // some info about all failed
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.