Dea*_*hen 2 javascript promise
为什么下面的代码无法捕获错误?“捕获”不起作用,错误抛出并退出。我在 nodeJs 8.9 上运行代码
new Promise(function(resolve,reject){
console.log('construct a promise...')
setTimeout(() => {
throw new Error('async operation failure!')
},1000)
})
.then(() => {
//never happen
console.log('happen?wrong!!!')
})
.catch(e => {
console.warn('execute promise failure! catch it')
})
Run Code Online (Sandbox Code Playgroud)
如果删除 setTimeout,则“捕获”有效
new Promise(function(resolve,reject){
console.log('construct a promise...')
throw new Error('async operation failure!')
})
.then(() => {
//never happen
console.log('happen?wrong!!!')
})
.catch(e => {
console.warn('execute promise failure! catch it')
})
Run Code Online (Sandbox Code Playgroud)
为什么会这样?请帮忙,谢谢!
要理解为什么不能从回调中抛出错误,setTimeout您需要了解一些概念。
当程序运行时,信息存储在称为堆栈的数据结构中。当一个方法被调用时,信息被存储在堆栈上,直到该方法返回。由于方法通常包含对其他方法的调用,因此堆栈会增长和缩小,直到所有方法都返回为止(这通常是程序的结尾)。当一个错误被抛出时,它会被传递到尚未返回的函数调用堆栈,直到它被捕获和处理,或者到达“main”方法,这通常会导致程序崩溃。
事件循环是 Javascript 中异步功能的动力。当setTimeout或任何其他异步方法被调用时,回调被放置在一个称为事件循环的队列中。当 javascript 运行时执行程序并到达堆栈的末尾(例如,所有方法都已返回)而不是仅仅退出程序时,它首先查看事件循环中是否有任何内容,如果有则开始执行它导致堆叠以再次增长和缩小。当事件循环中没有任何剩余,并且堆栈为空时,程序可以自由退出。
这意味着当您调用setTimeout传递给方法的回调时,最终会在不同的堆栈帧中执行。这意味着错误不可能被抛出堆栈并被 Promise 捕获,因为创建 Promise 的堆栈已经完成执行并且不再存在。
我建议观看有关该主题的视频,它非常详细,可以帮助您想象正在发生的事情:事件循环到底是什么?
setTimeout()有它自己的异步回调。该回调中的异常只会返回到计时器事件系统,它们不会去其他任何地方,因此 Promise 无法捕获它们。您应该reject(...)从 内部调用setTimeout()。
new Promise(function(resolve,reject){
console.log('construct a promise...')
setTimeout(() => {
reject(new Error('async operation failure!'));
},1000)
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1738 次 |
| 最近记录: |