Tob*_*ann 1 javascript exception promise es6-promise
编辑:
承诺不会隐藏异常,正如优秀(接受)的答案所指出的那样.我想详细说明承诺中的例外是如何不可见的:
我正在研究一个使用专有库来进行ajax调用的项目.现在,如果ajax-call回调中的某些内容出错,则会抛出异常.然后,此异常将触发reject()被调用,然后以静默方式丢弃.实际上,异常并未隐藏,而是在空错误回调中进一步向下处理代码.这最终导致甚至很难识别出错误的情况.
原来的问题是:
我知道我可以在我的所有承诺中添加一个catch-block,并在那里添加console.log错误.在我的用例中,我需要在调用堆栈的更高级别捕获异常.
http://jamesknelson.com/are-es6-promises-swallowing-your-errors/
在另一个关于SO的问题中,接受的答案还提出了阻塞:
Javascript默默地吞下Promise中抛出的异常.
不,它没有.在promise执行器(您传递的函数new Promise)或then/ catchhandler中抛出的异常用作拒绝承诺的值.如果您有未处理的拒绝,任何体面的实现也会记录控制台错误.例如,请在最新版本的Chrome或Firefox中试用:
new Promise(() => { throw new Error("Unhandled"); })Run Code Online (Sandbox Code Playgroud)
在控制台中,您会发现:
Uncaught (in promise) Error: Unhandled
at Promise (js:13)
at new Promise ()
at js:13
很快,NodeJS将开始终止未处理拒绝的过程,就像未处理的异常一样.因为拒绝是例外.
我不想在我的所有承诺中添加一个捕获块.
你不必.承诺的规则是你要么退还承诺,要么处理拒绝; 几乎从来没有.(你很少做到这两点,例如当你"包装"发生的错误以使其更高级别时.)所以你只需要一个catch不会传播给调用者的承诺.最佳做法是尽可能地传播到最高级别,然后在那里处理它们.大多数时候你不写一个catch因为你正在宣传这个承诺.
我是否可以通过这种方式对本机Promise进行修补(或其他方式),以防止我的异常隐藏?
好吧,他们再也没有.您可以替换Promise和Promise.prototype.then让他们报告异常到控制台,但你最终会报告说,在事情处理的后续处理程序,不应该报道.例如:
// NOT RECOMMENDED
const RealPromise = Promise;
Promise = class Promise extends RealPromise {
constructor(executor) {
super((resolve, reject) => {
try {
executor(resolve, reject);
} catch (e) {
console.error(e);
reject(e);
}
});
}
then(onResolved, onRejected) {
return super.then(val => {
try {
return onResolved(val);
} catch (e) {
console.error(e);
throw e;
}
}, onRejected);
}
};
new Promise(() => {
throw new Error("Handled");
}).catch(e => {
console.log("But I handled it!");
});Run Code Online (Sandbox Code Playgroud)
......但是你可以看到,这不是一个好主意.
如果你遵循传播或处理规则,你应该没有内置的承诺.
它也可能值得注意async/ await语法,从ES2017开始是新的:当使用async/时await,promise promise被用作异常,关闭圆圈:
function foo() {
return new Promise((resolve, reject) => {
setTimeout(reject, 500, "Failed");
});
}
(async () => {
try {
await foo();
} catch (e) {
console.log("Got error: ", e);
}
})();Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |