决定此代码输出的JavaScript规则是什么?:

Promise.resolve()
    .then(() => console.log("Microtask 1"))
    .then(() => console.log("Microtask 11"));

Promise.resolve()
    .then(() => console.log("Microtask 2"))
    .then(() => console.log("Microtask 22"))

以下是输出:

Microtask 1
Microtask 2
Microtask 11
Microtask 22

但为什么这不是输出?:

Microtask 1
Microtask 11
Microtask 2
Microtask 22

推荐答案

您看到的输出是因为Microtask 11微任务直到Microtask 1的微任务运行才会排队,此时Microtask 2的微任务已经在队列中等待.因此,顺序是(跳过一些细节;更多信息如下):

  1. Microtask 1个队列微任务
  2. Microtask 2个队列微任务
  3. Task is compelete, start processing microtasks:
    1. Execute microtask queued in #1
      • 输出Microtask 1
      • Microtask 11个队列微任务
    2. Execute microtask queued in #2
      • 输出Microtask 2
      • Microtask 21个队列微任务
    3. Execute microtask queued in #3.1
      • 输出Microtask 11
    4. Execute microtask queued in #3.2
      • 输出Microtask 21

因此,

Microtask 1
Microtask 2
Microtask 11
Microtask 21

100:编写依赖于断开的Promise Chains/微任务序列的执行顺序的代码是自找麻烦的.:-)你只能根据已经达成的promise 进行推理,当然,在正常情况下,你不知道promise 什么时候会达成(甚至if).相反,如果您需要特定的订单,请将链条连接到ensure订单.


再次跳过细节:为了保持简短和清晰,我对主要解释中的内容进行了一些润色,但为了准确起见,我们来看看:

Promise.resolve()
    .then(() => console.log("Microtask 1"))
    .then(() => console.log("Microtask 11"));

...就这样,忽略了让事情变得简单的第二条promise 链.

以下是代码执行方式(我的blog post On Promise术语在阅读以下内容时可能会有所帮助):

  1. 执行Promise.resolve(),创建使用值undefined实现in this particular case的promise .
  2. 执行.then(() => console.log("Microtask 1")),创建一个新函数,并使用它在第1步中的promise 上调用then.这将创建并返回一个新promise ,in this particular case,将微任务排队以调用该函数,因为该promise 已经兑现.
  3. 执行.then(() => console.log("Microtask 11")),创建一个新函数,并使用它在第2步中的promise 上调用then.这将创建并返回一个新的promise (我们在该代码中丢弃它),并且由于第2步中的promise 仍然悬而未决,因此将该函数作为履行处理程序添加到其中.
  4. 运行此代码的任务结束,因此JavaScript引擎处理微任务队列:
    1. 执行队列中的第一个微任务:
      1. 调用函数Logging Microtask 1.
      2. 由于函数返回undefined,而不是promise 或其他thenable,因此引擎用undefined.履行步骤2中的promise (如果函数已返回promise 或其他支持,则promise 将改为resolved to,即返回的promise ).
        • 将微任务排队以调用在第3步中在该promise 上注册的履行处理程序,该处理程序在被调用时将记录Microtask 11.
    2. 执行队列(remember that we're ignoring the other promise chain in this description, so in this case the next microtask is the one logging 104 that was just added to the queue, not the one logging 106)中的下一个微任务:
      1. 调用函数Logging Microtask 11.
      2. 由于该函数返回undefined,这不是promise 或其他使能,因此引擎用undefined.履行步骤3中的promise
        • 这不会做任何事情,因为该promise 没有注册任何履行处理程序.

Javascript相关问答推荐

将数据从strapi提取到next.js,但响应延迟API URL

基于变量切换隐藏文本

如何在Obsidian dataview中创建进度条

Promise Chain中的第二个useState不更新

如何在bslib nav_insert之后更改导航标签的CSS类和样式?

从包含数百行的表中获取更改后的值(以表单形式发送到后端)的正确方法是什么?

Angular 订阅部分相互依赖并返回数组多个异步Http调用

正则表达式,允许我匹配除已定义的子字符串之外的所有内容

有条件重定向到移动子域

从另一个数组中的对应行/键值对更新数组中的键值对对象

当从其他文件创建类实例时,为什么工作线程不工作?

如何使用Astro优化大图像?

在渲染turbo流之后滚动到元素

如何根据输入数量正确显示alert ?

如何修复错误&语法错误:不能在纯react 项目中JEST引发的模块&之外使用导入语句?

如何使用[ModelJSON,ArrayBuffer]调用tf.loadGraphModelSync

为什么NULL不能在构造函数的.Prototype中工作

为什么我不能使用其同级元素调用和更新子元素?

使用Java脚本筛选数组中最接近值最小的所有项

打字脚本中的函数包装键入