关于这段代码片段执行顺序的问题
Questions about the order of execution of this code snippet
所以我最近一直在阅读关于 Javascript promises 的教程。
这里有一个例子用来解释宏任务队列(即事件循环)和微任务队列。
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
,我们把它放到宏任务队列中,
- 第三行,我们有一个事件处理程序,我们将处理程序放在宏任务队列中等待被触发
那么,因为microtask的优先级高于macrotask。我们运行 承诺第一。之后,我们将宏任务队列中的第一个任务出队,即 setTimeout
。所以根据我的理解,错误应该被 setTimeout
.
里面的函数捕获
请指正。
你对步骤 3) 的看法是错误的。处理程序将同步添加。然后微任务队列得到 运行,promise 被拒绝。由于尚未添加 .catch
处理程序,因此抛出未处理的拒绝。
而且我认为您在 添加回调时 和 执行回调时 之间混为一谈。考虑这种情况:
(new Promise).then(function callback() { });
回调将同步添加,但永远不会被调用,因为承诺永远不会解决。在这种情况下:
Promise.resolve().then(function callback() { });
回调再次被同步添加,但 promise 解析发生在微任务中,因此回调将在 a tick 后执行 。
所以我最近一直在阅读关于 Javascript promises 的教程。
这里有一个例子用来解释宏任务队列(即事件循环)和微任务队列。
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
,我们把它放到宏任务队列中, - 第三行,我们有一个事件处理程序,我们将处理程序放在宏任务队列中等待被触发
那么,因为microtask的优先级高于macrotask。我们运行 承诺第一。之后,我们将宏任务队列中的第一个任务出队,即 setTimeout
。所以根据我的理解,错误应该被 setTimeout
.
请指正。
你对步骤 3) 的看法是错误的。处理程序将同步添加。然后微任务队列得到 运行,promise 被拒绝。由于尚未添加 .catch
处理程序,因此抛出未处理的拒绝。
而且我认为您在 添加回调时 和 执行回调时 之间混为一谈。考虑这种情况:
(new Promise).then(function callback() { });
回调将同步添加,但永远不会被调用,因为承诺永远不会解决。在这种情况下:
Promise.resolve().then(function callback() { });
回调再次被同步添加,但 promise 解析发生在微任务中,因此回调将在 a tick 后执行 。