javascript - Promise.prototype.then 链在调用堆栈、WebAPI 部分和微任务队列方面会发生什么?
问题描述
我想知道这个代码片段中.then
关于堆栈、WebAPI 部分和微任务队列的 s 链发生了什么。我在Loupe中尝试过,但似乎没有注册.then
s。
setTimeout(function() {console.log(2)}, 0);
Promise.resolve(1)
.then((value) => {console.log(value)}) //
.then((value) => {console.log(value)}) //
事实上,.then
s 必须等到前一个.then
返回一个已解决的承诺(.then
链接),这让我感到困惑。我不确定这看起来如何。我的猜测是:
脚本第一次(也是唯一一次)运行时,它会识别.then
为返回承诺的异步函数 - 所以它在 WebAPI 部分中执行此操作。第一个.then
take ( Promise.resolve1
) 的承诺是同步的,并且会立即解决,因此.then
的回调 ( (value) => {console.log(value)}
) 会立即放入微任务队列中。也许脚本看到有一个.then
链条并留下其余部分,因为它们都相互依赖。
没有什么可看的了,'main'/脚本从堆栈中弹出。现在,一直在微任务队列中等待的回调被压入堆栈并执行。太好了,回调记录 5 并且回调帮助第一个.then
返回已履行的承诺,undefined
并将其作为“结果”。第二个.then
立即被要求接受这个新的承诺。我将在这里停下来,因为我没有信心。
对调用堆栈、WebAPI“线程”或“区域”以及微堆栈队列进行分步说明会很棒。
解决方案
回调帮助第一个
.then
返回一个履行的承诺undefined
作为它的“结果”。第二个.then
立即被要求接受这个新的承诺。
不,.then(…)
这两个方法都在主脚本的初始执行期间被调用,并且都立即返回一个新的 Promise(但尚未解决)。Promise 只是一个普通对象,可以像任何其他值一样传递和记录,脚本正常执行方法调用。
除了返回新的Promise 之外,.then(…)
调用所做的是将回调注册为原始 Promise 上的履行/拒绝处理程序 - 而不执行它们。(当承诺已经实现时,就像您给出的示例一样,它还会立即安排处理程序运行,将它们放入微任务队列中)。
在微任务上执行第一个处理程序并记录数字后,它的返回值用于解析.then()
已返回的承诺。在该承诺上注册的任何处理程序都将被安排运行。因此,当第一个微任务完成时,第二个微任务已经在队列中等待并使用结果值执行第二个处理程序,使其成为 log undefined
,然后解决链中的最后一个承诺 - 但没有更多的处理程序可以调度,微任务队列将为空。
推荐阅读
- python - Python:如何使用文件而不是文件夹制作 zip
- ajax - laravel-ajax 响应为空
- python-3.x - 内面板无反应
- python - 使用 OpenCV 和 ffpyplayer 进行音视频同步
- c - 在诅咒中调整窗口大小
- groovy - 有没有办法设置 toJson() 的递归深度?
- r - 修改ggplot2中的图例
- flutter - Flutter PopupMenuButton - 选择时不要关闭菜单
- selenium-webdriver - Python:选择隐藏选项使用 Selenium 具有 aria-hidden=true 的元素
- postgresql - postgres 过程给出错误:类型时间戳的无效输入语法:“选择 CURRENT_TIMESTAMP - INTERVAL '7 day'”