javascript - 关于这段代码执行顺序的问题
问题描述
所以这些天我一直在阅读关于 Javascript 承诺的教程。
这是一个用于解释宏任务队列(即事件循环)和微任务队列的示例。
let promise = Promise.reject(new Error("Promise Failed!"));
promise.catch(err => alert('caught'));
// no error, all quiet
window.addEventListener('unhandledrejection', event => alert(event.reason));
它说因为promise.catch
在最后一行捕获了错误,所以事件处理程序永远不会运行。我可以理解这一点。但后来他稍微调整了这个例子。
let promise = Promise.reject(new Error("Promise Failed!"));
setTimeout(() => promise.catch(err => alert('caught')));
// Error: Promise Failed!
window.addEventListener('unhandledrejection', event => alert(event.reason));
这次他说事件处理程序将首先运行并捕获错误,然后最终promise.catch
捕获错误。
关于第二个示例,我不明白的是,为什么事件处理程序在promise.catch
?
我的理解是,
- 第一行,我们首先遇到一个promise,我们把它放到微任务队列中。
- 第二行,我们有一个
setTimeout
,我们把它放在宏任务队列中, - 第三行,我们有一个事件处理程序,我们将处理程序放在等待被触发的宏任务队列中
然后,因为微任务的优先级高于宏任务。我们首先运行承诺。之后,我们将宏任务队列中的第一个任务出列,即setTimeout
. 所以根据我的理解,错误应该是被里面的函数捕获的setTimeout
。
请纠正我。
解决方案
你错了第3步)。处理程序将同步添加。然后微任务队列开始运行,promise 被拒绝。由于.catch
尚未添加任何处理程序,因此会引发未处理的拒绝。
而且我认为您在添加回调和执行回调之间混为一谈。考虑这种情况:
(new Promise).then(function callback() { });
回调将同步添加,但永远不会被调用,因为承诺永远不会解决。在这种情况下:
Promise.resolve().then(function callback() { });
回调再次同步添加,但承诺解决发生在微任务中,因此回调将在稍后执行。
推荐阅读
- three.js - ThreeJS WebVR 摄像头设置
- android - 单选 RecyclerView TextView
- c# - 从控制台打开 WPF 应用程序并关闭控制台窗口
- ios - DispatchQueue.main.asyncAfter 带开/关开关
- html - 如果我不先打开图片的链接,图片链接不起作用
- c - Mono embed API 在运行时修改方法体
- lua - Conky cpubar 以错误的方式填充
- node.js - AWS Alexa V2 中的 SSML 支持
- html - Z-Index问题,我没有解释
- c - 想要永远闪烁,直到我在 nodemcu 中按下 OFF