我会使用间接承诺:
var d1 = $q.defer(), d2 = $q.defer();
function NetworkError(reason) { this.reason = reason; }
eventResourcesCall = $http.jsonp('https://apicall/to/serverA').then(
function(response) {
d1.resolve(response);
},
function(err) {
d1.resolve(new NetworkError(err));
}
);
eventsDetailsCall = $http.get('https://apicall/to/serverB').then(
function(response) {
d2.resolve(response);
},
function(err) {
d2.resolve(new NetworkError(err));
}
);
$q.all([d1, d2]).then(function(values){
var eventResources = values[0], eventsDetails = values[1];
if( eventResources instanceof NetworkError ) {
// handle error
}
else {
// eventResources is good, use it
}
// and so on...
});
因此,间接承诺总是被解决并且all()
成功。但是分辨率值可能属于特殊NetworkError
类,它表示该请求中的实际错误。
这绝对是庞大的,但可以通过一些实用方法来改进,例如:
function makeIndirectPromise(httpPromise) {
var ret = $q.defer();
httpPromise.then(
function(response) {
ret.resolve(response);
},
function(err) {
ret.resolve(new NetworkError(err));
}
);
return ret.promise;
}
上面的代码更改为:
function NetworkError(reason) { this.reason = reason; }
function makeIndirectPromise(httpPromise) { /* see above */ }
eventResourcesCall = makeIndirectPromise($http.jsonp('https://apicall/to/serverA'));
eventsDetailsCall = makeIndirectPromise($http.get('https://apicall/to/serverB'));
$q.all([eventResourcesCall, eventsDetailsCall]).then(function(values){
var eventResources = values[0], eventsDetails = values[1];
if( eventResources instanceof NetworkError ) {
// handle error
}
else {
// eventResources is good, use it
}
// and so on...
});