我怎样才能使用承诺来捕捉错误,当他们可能不被包装在一个承诺?

背景

我正在使用承诺,我有许多function,可能会或可能不会返回一个承诺,可能会或可能不会失败,如下面的示例中:

//does not return a Promise, simply a string let goodFun = function(){ return "I like bananas!"; }; //blows up! let badFun = function(){ throw "A general error blaahh!"; }; //You get the point ... 

由于这些函数可能会也可能不会返回Promises,并且可能会也可能不会失败,所以我需要等待所有这些函数的执行。 为了实现这一点,我有一个函数来调用它们,并等待它们的执行:

 let asyncFun = function(){ return Promise.all([badFun(), goodFun()]); }; 

问题

到现在为止还挺好。 我的代码调用asyncFun ,我期望它的一些函数实际上失败。 为了做好准备,我加了一句话:

 let executor = function(){ let numbsArray = [1, 2, 3]; let respArray = []; for(let num of numbsArray){ respArray.push( asyncFun() .catch( error => console.log(`I failed with ${error} and ${num}`)) ); } return Promise.all(respArray); }; 

问题是这个catch并没有捕捉任何东西!

即使在调用executor程序的函数中添加一个catch也没什么用处!

 executor() .catch(error => console.log("Failed miserably to catch error!")); 

研究

我不明白为什么我的catch子句没有捕捉到exception。 为了找出答案,我读了这个讨论:

  • 如何做出承诺失败的笑话

这使我相信,我所有的functiongoodFunbadFun ,无论如何,都必须回报一个承诺。

这对我来说是令人困惑的,因为根据MDN文档 ,数组可能包含一个Promise或一个结果(如string或数字)。

我也想避免添加更多的锅炉板代码到我的function….

题:

  1. 如何修复我的代码,使捕获工作增加一个最小或样板代码?

 let goodFun = function() { return "I like bananas!"; }; let badFun = function() { throw "A general error blaahh!"; }; let asyncFun = function() { return Promise.all([badFun(), goodFun()]); }; let executor = function() { let numbsArray = [1, 2, 3]; let respArray = []; for (let num of numbsArray) { respArray.push( asyncFun() .catch(error => console.log(`I failed with ${error} and ${num}`)) ); } return Promise.all(respArray); }; executor() .catch(error => console.log("Failed miserably to catch error!")); 

.catch es不工作的原因是错误正在同步抛出。 代码执行甚至从来没有执行.catch()指令来build立一个catch处理程序,因为错误已经被抛出,代码执行已经到了别处。 如果你把所有的东西都包装在一个普通的try-catch ,我想你会看到它抓住了你所抛出的错误。

例:

 let goodFun = function() { return "I like bananas!"; }; //blows up! let badFun = function() { throw "A general error blaahh!"; }; try { Promise.all([goodFun(), badFun()]) .then(results => console.log(results)) .catch(error => console.error(error)) } catch (e) { console.error("Wups, I caught an error. This wasn't supposed to happen.", e); }