在第一级尝试抓住错误在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.then
和promise.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 a
和throw(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语句将处理它。