在第一级尝试抓住错误在JavaScript承诺

所以,我想我的第一级捕获是处理错误的一个。 无论如何要把我的错误传播到第一次接触?

参考代码,不工作(还):

Promise = require('./framework/libraries/bluebird.js'); function promise() { var promise = new Promise(function(resolve, reject) { throw('Oh no!'); }); promise.catch(function(error) { throw(error); }); } try { promise(); } // I WANT THIS CATCH TO CATCH THE ERROR THROWN IN THE PROMISE catch(error) { console.log('Caught!', error); } 

有了新的asynchronous/等待语法,你可以实现这一点。 请注意,在撰写本文时,并不是所有的浏览器都支持,你可能需要用babel (或者类似的东西)来传递你的代码。

 // Because of the "async" keyword here, calling getSomeValue() // will return a promise. async function getSomeValue() { if (somethingIsNotOk) { throw new Error('uh oh'); } else { return 'Yay!'; } } async function() { try { // "await" will wait for the promise to resolve or reject // if it rejects, an error will be thrown, which you can // catch with a regular try/catch block const someValue = await getSomeValue(); doSomethingWith(someValue); } catch (error) { console.error(error); } } 

您不能使用try-catch语句来处理asynchronous抛出的exception,因为在引发任何exception之前函数已经“返回”了。 你应该使用promise.thenpromise.catch方法,它们代表try-catch语句的asynchronous等价物。

你需要做的是返回承诺,然后链接另一个.catch

 function promise() { var promise = new Promise(function(resolve, reject) { throw('Oh no!'); }); return promise.catch(function(error) { throw(error); }); } promise().catch(function(error) { console.log('Caught!', error); }); 

承诺是可链接的,所以如果一个承诺重新抛出一个错误,它将被委托下一个.catch

顺便说一句,你不需要在throw语句周围使用括号( throw athrow(a)相同)。


如果您在Node.js中运行此代码,并且由于某种原因您不允许编辑promise函数,则可以使用域来执行此操作。 请注意,域并不是最容易处理的事情,并且在某些情况下会出现一些恼人的边缘情况。 除非你真的必须,否则我强烈推荐使用promise。

没有! 这是完全不可能的,因为承诺本质上是asynchronous的。 当抛出exception时,try-catch子句将完成执行(并且时间旅行仍然不会被发明)。

相反,从所有的函数中返回promise,并在它们上挂钩一个error handling程序。

我经常发现需要确保一个Promise被返回,几乎同样需要处理一个本地错误,然后可以重新抛出它。

 function doSomeWork() { return Promise.try(function() { return request.get(url).then(function(response) { // ... do some specific work }); }).catch(function(err) { console.log("Some specific work failed", err); throw err; // IMPORTANT! throw unless you intend to suppress the error }); } 

这种技术(Promise.try / catch)的好处是,你可以开始/确保一个没有解决/拒绝要求的Promise链,这很容易被遗漏,并产生一个debugging噩梦。

为了扩大江户的答案,如果你想捕捉asynchronous函数的错误,你不想等待。 您可以在函数的末尾添加一个await语句。

 async function() { try { const asyncResult = someAsyncAction(); // "await" will wait for the promise to resolve or reject // if it rejects, an error will be thrown, which you can // catch with a regular try/catch block const someValue = await getSomeValue(); doSomethingWith(someValue); await asyncResult; } catch (error) { console.error(error); } } 

如果someAsyncAction失败,catch语句将处理它。