javascript - 运行 并行承诺但分别处理拒绝
javascript - run promises in parallel but handle rejections separately
我使用 bluebird.js
map
函数对我使用的外部 API 执行并行请求。
每当任何内部承诺被拒绝时,map
函数也会被拒绝(我知道这是设计使然)。
我想知道是否有任何方法可以并行 运行 promises 但分别处理每个拒绝,而不会使整个 Promise 失败。
I was wondering if there is any way to run promises in parallel but handle each rejection separately, and not fail the entire Promise.
来处理它们
const all = Promise.map(somethings, function(something) {
return doSomething(something).catch(function(e) {
return handleIt(e); // normal completion, no rejection or exception
});
});
另见 一般情况。
我会使用 .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());
});
如果没有任何具有纯 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})));
我使用 bluebird.js
map
函数对我使用的外部 API 执行并行请求。
每当任何内部承诺被拒绝时,map
函数也会被拒绝(我知道这是设计使然)。
我想知道是否有任何方法可以并行 运行 promises 但分别处理每个拒绝,而不会使整个 Promise 失败。
来处理它们I was wondering if there is any way to run promises in parallel but handle each rejection separately, and not fail the entire Promise.
const all = Promise.map(somethings, function(something) {
return doSomething(something).catch(function(e) {
return handleIt(e); // normal completion, no rejection or exception
});
});
另见
我会使用 .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());
});
如果没有任何具有纯 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})));