潜入Promise,我发现了让我困惑的事情。然而,我意识到发生了什么,并决定在这里分享给其他可能碰到它的人。
我有以下JavaScript:
new Promise(function (resolve, reject) {
foo();
setTimeout(function () {
resolve();
}, 400);
}).catch(function (err) {
console.log('Caught it:', err.message);
});
当我运行它时,我得到:
抓住它:foo未定义
预期结果如何。但是,如果我尝试在foo()
回调中拨打setTimeout
,请执行以下操作:
new Promise(function (resolve, reject) {
setTimeout(function () {
foo();
resolve();
}, 400);
}).catch(function (err) {
console.log('Caught it:', err.message);
});
我明白了:
ReferenceError: foo is not defined at Timeout._onTimeout (C:\Users\Hristiyan\Desktop\promise.js:3:13) at tryOnTimeout (timers.js:224:11) at Timer.listOnTimeout (timers.js:198:5)
问题:为什么我得不到相同的结果?为什么用catch()
定义的处理程序不能处理错误?我的意思是,错误发生在相同的代码块下?
答案 0 :(得分:0)
发生这种情况的原因是因为错误发生在一个单独的调用堆栈中,没有什么可以捕获它。
在第一个示例中,错误发生在promise解析器中,这是Promise提供的函数。然后,Promise可以捕获错误。如果每个数字代表更深层次的一个级别,它看起来会像这样:
Resolver抛出错误,它向上移动,并被Promise捕获。
在第二个例子中,错误发生稍后,在这种情况下 - 在400ms之后,当Promise的调用堆栈早已消失并完成其执行而没有错误。类似的东西:
* 400毫秒后*
setTimeout
处理程序(抛出)(上面没有任何内容可以抓住)因此错误发生在另一个调用堆栈上,没有任何东西可以捕获。即使它在Promise的代码块下,它也不在调用堆栈中。因此,为了使代码按预期工作,需要一个catch块来捕获错误。捕获时,我们通过调用其reject
处理程序通知Promise:
new Promise(function(resolve, reject) {
setTimeout(function() {
try {
foo();
} catch (e) {
return reject(e);
}
resolve();
}, 400);
}).catch(function(err) {
console.log('Caught it:', err.message);
});