我一直试图等待Angular的$ q的几个承诺,但似乎没有选择'等待所有即使被拒绝的承诺'.我创建了一个例子(http://jsfiddle.net/Zenuka/pHEf9/21/),我希望在所有承诺被解决/拒绝时执行一个函数,这可能吗?就像是:
$q.whenAllComplete(promises, function() {....})
Run Code Online (Sandbox Code Playgroud)
编辑:在示例中,您看到第二个服务失败,并且在此之后立即$q.all().then(..., function(){...})执行函数.我想等待第五个承诺完成.
Zen*_*uka 30
好吧,我自己实现了一个基本版本(我只想等待一系列的承诺).任何人都可以扩展这个或创建一个更清洁的版本,如果他们想:-)检查jsfiddle以查看它在行动:http://jsfiddle.net/Zenuka/pHEf9/
angular.module('test').config(['$provide', function ($provide) {
$provide.decorator('$q', ['$delegate', function ($delegate) {
var $q = $delegate;
// Extention for q
$q.allSettled = $q.allSettled || function (promises) {
var deferred = $q.defer();
if (angular.isArray(promises)) {
var states = [];
var results = [];
var didAPromiseFail = false;
if (promises.length === 0) {
deferred.resolve(results);
return deferred.promise;
}
// First create an array for all promises with their state
angular.forEach(promises, function (promise, key) {
states[key] = false;
});
// Helper to check if all states are finished
var checkStates = function (states, results, deferred, failed) {
var allFinished = true;
angular.forEach(states, function (state, key) {
if (!state) {
allFinished = false;
}
});
if (allFinished) {
if (failed) {
deferred.reject(results);
} else {
deferred.resolve(results);
}
}
}
// Loop through the promises
// a second loop to be sure that checkStates is called when all states are set to false first
angular.forEach(promises, function (promise, key) {
$q.when(promise).then(function (result) {
states[key] = true;
results[key] = result;
checkStates(states, results, deferred, didAPromiseFail);
}, function (reason) {
states[key] = true;
results[key] = reason;
didAPromiseFail = true;
checkStates(states, results, deferred, didAPromiseFail);
});
});
} else {
throw 'allSettled can only handle an array of promises (for now)';
}
return deferred.promise;
};
return $q;
}]);
}]);
Run Code Online (Sandbox Code Playgroud)
Mic*_*pat 18
类似于如何all()返回已解析值的数组/散列,Kris Kowal的Q allSettled()函数返回一组对象,其外观如下:
{ state: 'fulfilled', value: <resolved value> }
Run Code Online (Sandbox Code Playgroud)
要么:
{ state: 'rejected', reason: <rejection error> }
Run Code Online (Sandbox Code Playgroud)
由于这种行为非常方便,我已将该函数移植到Angular.js的$ q:
angular.module('your-module').config(['$provide', function ($provide) {
$provide.decorator('$q', ['$delegate', function ($delegate) {
var $q = $delegate;
$q.allSettled = $q.allSettled || function allSettled(promises) {
// Implementation of allSettled function from Kris Kowal's Q:
// https://github.com/kriskowal/q/wiki/API-Reference#promiseallsettled
var wrapped = angular.isArray(promises) ? [] : {};
angular.forEach(promises, function(promise, key) {
if (!wrapped.hasOwnProperty(key)) {
wrapped[key] = wrap(promise);
}
});
return $q.all(wrapped);
function wrap(promise) {
return $q.when(promise)
.then(function (value) {
return { state: 'fulfilled', value: value };
}, function (reason) {
return { state: 'rejected', reason: reason };
});
}
};
return $q;
}]);
}]);
Run Code Online (Sandbox Code Playgroud)
归功于: