有两种选择:
解决
Dojo 承诺没有提供任何工具来明确地管理这种情况,比如'bluebird's Promise.settle 或 when's when.settle。所以我们几乎必须自己创建它:
function settle(promises){ // assuming "dojo/promise/all" and "dojo/Deferred"
var d = new Deferred();
var countdownLatch = promises.length;
var results = [];
promises.forEach(function(p, i){
p.then(function(v){
results[i] = {state: "fulfilled", value: v};
countdownLatch--;
if(countdownLatch === 0) d.resolve(results);
}, function(err){
results[i] = {state: "rejected", err: err };
countdownLatch--;
if(countdownLatch === 0) d.resolve(results);
});
});
return d; // dojo mixes deferred and promises because it's an older API
}
这会让你这样做:
settle(myPromisesArray).then(function(results){
results.forEach(function(res){
console.log(res.state); // you can `if` on it to check a particular promise
});
});
反映
更现代的方法是创建一个反射方法,该方法接受一个承诺并返回一个承诺,该承诺总是与包含前一个承诺状态的对象实现。这是 Bluebird 正在探索的方向,可能会包含在 V3 中。
function reflect(promise){
return promise.then(function(v){ return {state: "fulfilled", value: v }; },
function(e){ return {state: "rejected" , error: e }; });
}
这可以让您进行不同的聚合,这使得上面的 settle 成为一个私人案例:
function settle(promises){
return all(promises.map(reflect));
}