我使用bluebird.js
map
函数对我使用的外部API执行并行请求
每当任何内部承诺被拒绝时,map
函数也会被拒绝(我知道这是设计)。
我想知道是否有任何方法可以并行运行promises但是分别处理每个拒绝,并且不会使整个Promise失败。
答案 0 :(得分:3)
我会在地图中使用.reflect
来获取承诺检查结果:
const all = Promise.map(items, item => doSomething(item).reflect());
all.then(items => {
// will contain an array of the promises that fulfilled correctly
let fulfilled = items.filter(x => x.isFulfilled()).map(x => x.value()));
// will contain an array of the promises that rejected
// so you can handle the errors
let rejected = items.filter(x => x.isRejected()).map(x => x.reason());
});
答案 1 :(得分:2)
我想知道是否有任何方法可以并行运行promises但是分别处理每个拒绝,并且不会使整个Promise失败。
const all = Promise.map(somethings, function(something) {
return doSomething(something).catch(function(e) {
return handleIt(e); // normal completion, no rejection or exception
});
});
另请参阅Wait until all ES6 promises complete, even rejected promises。
答案 2 :(得分:-1)
如果没有任何具有纯ES6承诺的库,您可能会有这样的方法。在这种情况下,promiseAll
函数将尊重已解决的承诺以及被拒绝的承诺。
function promisify(fun){
return (data) => new Promise((resolve,reject) => fun(data, (err,res) => err ? reject(err) : resolve(res)));
}
function async(data, callback){
data.val+= " msec";
Math.random() < 0.5 ? setTimeout(_ => callback(false,data.val),data.dur)
: setTimeout(_ => callback("error"),data.dur);
}
function myNormalCallback(resultObject){
console.log("Promise " + resultObject.count + " returned " + resultObject.result);
}
function myErrorCallback(errorObject){
console.log("Promise " + errorObject.count + " returned " + errorObject.error);
}
function promiseAll(proms){
return new Promise((v,x) => { var results = new Array(proms.length).fill(void 0);
proms = proms.map((prom,i) => prom.then(res => {results[i] = res;
results.indexOf(void 0) === -1 && v(results);
})
.catch(err => {results[i] = err;
results.indexOf(void 0) === -1 && v(results);
}));
});
}
var datas = [{val: 100, dur: 1000},{val: 200, dur: 2000},{val: 300, dur: 3000}],
proms = datas.map(data => promisify(async)(data));
promiseAll(proms).then(results => results.map((res,i) => res === "error" ? myErrorCallback({count:i,error: res})
: myNormalCallback({count:i,result: res})));