我在一个简单的脚本中逐字记录:
Promise.all(links.map(function (l) {
return Promise.resolve(require(l).r2gSmokeTest())
.then((v:any) => ({path: l, result: v}));
}))
.then(function(results){
})
.catch(function(e){
}):
问题是,如果require()
调用因任何原因抛出错误,则承诺链不会抓住它。
是最简单的方法,可以避免将Promise.all包装在一个函数中,如下所示:
const getAllPromises = function(links){
return Promise.resolve(null).then(function(){
return Promise.all(links.map(function (l) {
return Promise.resolve(require(l).r2gSmokeTest())
.then((v:any) => ({path: l, result: v}));
}));
在我看来,也许Promise.all应该有一个不同的API,如:
Promise.all(function(){
return values.map(v => whatever);
});
如果在Promise链中没有调用Promise.all,那么任何错误都会被捕获......
答案 0 :(得分:2)
使用不能抛出的async function
- 它只会在发生异常时返回被拒绝的承诺:
Promise.all(links.map(async function (l) {
const v: any = await require(l).r2gSmokeTest();
return {path: l, result: v};
}))
通常,对任何执行异步操作的函数的期望是始终返回promise和never throw synchronously。如果有必要,您的map
回调应该遵守该问题,并在try … catch (e) { return Promise.reject(e); }
电话周围require
。您也可以考虑使用类似Bluebird's Promise.try
的帮助函数。
答案 1 :(得分:2)
您的require()
发生在Promise上下文之外的地图级别上,这就是为什么它会立即传播到全局级别,所以如果您只是将其包装到new Promise
它应该按预期处理错误:
Promise.all(links.map(function(l) {
return new Promise(resolve => resolve(require(l).r2gSmokeTest())) // <-- here
.then((v: any) => ({
path: l,
result: v
}));
}))
.then(function(results) {
})
.catch(function(e) {
}):