Javascript Promise.all可捕获错误的包装器

Javascript Promise.all可捕获错误的包装器,javascript,node.js,ecmascript-6,es6-promise,Javascript,Node.js,Ecmascript 6,Es6 Promise,我用一个简单的脚本逐字记录: 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(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}));
}));
在我看来,maybe Promise.all应该有不同的API,比如:

Promise.all(function(){
   return values.map(v => whatever);
});

这样,如果在承诺链中未调用Promise.all,则任何错误都可能被捕获…

使用不能抛出的
异步函数
,它只会在发生异常时返回被拒绝的承诺:

Promise.all(links.map(async function (l) {
  const v: any = await require(l).r2gSmokeTest();
  return {path: l, result: v};
}))

一般来说,对于任何执行异步操作的函数来说,期望总是返回一个承诺和。您的
map
callback应该遵守这一点,并且
try…catch(e){return Promise.reject(e);}
require
调用(如有必要)周围。您也可以考虑使用类似于.E/P>< P>的帮助函数,使用不能抛出的<代码>异步函数 -它只会在异常发生时返回拒绝的承诺:

Promise.all(links.map(async function (l) {
  const v: any = await require(l).r2gSmokeTest();
  return {path: l, result: v};
}))
一般来说,对于任何执行异步操作的函数来说,期望总是返回一个承诺和。您的
map
callback应该遵守这一点,并且
try…catch(e){return Promise.reject(e);}
require
调用(如有必要)周围。您也可以考虑使用帮助函数,如

< p>您的<代码>要求()/代码>发生在承诺上下文之外的映射级别上,这就是为什么它立即被传播到全局级别,因此如果您将其包装成<代码>新承诺< /代码>,它应该按照预期处理错误:

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) {

  }):
Promise.all(links.map)(函数(l){
返回新承诺(resolve=>resolve(require(l).r2gSmokeTest())//({
路径:l,
结果:v
}));
}))
.然后(函数(结果){
})
.catch(函数(e){
}):
您的
require()
发生在Promise上下文之外的映射级别上,这就是它会立即传播到全局级别的原因,因此,如果您只是将其包装到一个
新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) {

  }):
Promise.all(links.map)(函数(l){
返回新承诺(resolve=>resolve(require(l).r2gSmokeTest())//({
路径:l,
结果:v
}));
}))
.然后(函数(结果){
})
.catch(函数(e){
}):

你的问题到底是什么?@Bergi好像你明白了,抱歉没有那么清楚你的问题到底是什么?@Bergi好像你明白了,抱歉没有那么清楚,但是如果你答应了。all()。那么()在这种情况下,如果在
异步
函数中出现错误,
然后
是否会兑现承诺?我不确定它是否能通过我的测试,这是有效的,但我不确定为什么。如果您进一步解释它工作的原因,那就很好了,但是如果您确实承诺.all().then(),那么在这种情况下,
then
是否会在
async
函数中出现错误时遵守承诺?我不确定它是否能通过我的测试,这是有效的,但我不确定为什么。如果你能详细解释一下它为什么会起作用,我认为使用
Promise.resolve(null)
进行包装比使用执行者创建新的承诺更简单?@Olegzandr这取决于“simple”的定义,我认为“simple”意味着在尽可能少地更改源代码的情况下解决问题。如果你的不同,请澄清。请记住,
Promise.resolve(arg)
newpromise(resolve=>resolve(arg))的别名
,每个
。然后
都在链中创建一个新的Promise对象。这就是为什么在某种意义上调用
newpromise()
更简单的原因,因为您不必创建额外的承诺,也不必输入像
null
这样神奇的占位符值。我认为使用
Promise.resolve(null)
包装比与执行者一起创建新承诺更简单?@Olegzandr好吧,这取决于“简单”的定义,我认为“简单”意味着在尽可能少地更改源代码的情况下解决问题。如果你的不同,请澄清。请记住,
Promise.resolve(arg)
newpromise(resolve=>resolve(arg))的别名
,每个
。然后
都在链中创建一个新的Promise对象。这就是为什么在某种意义上调用
newpromise()
更简单的原因,因为您不必创建额外的承诺,也不必输入像
null
这样的神奇占位符值。