当我了解 microtask 和 Promise 时,我遇到了一个我不理解的行为

2024-03-01

我在 then() 回调中没有返回任何内容,在我看来输出应该是 1 5 7 2 6 3 4,但结果是 1 2 5 3 6 7 4,谁能告诉我为什么

Promise.resolve().then(function() {
    console.log('promise1');
    
    Promise.resolve().then(() => {
        console.log('promise2')

        Promise.resolve().then(() => {
            console.log('promise3')

            Promise.resolve().then(() => {
                console.log('promise4')
            })
        })
    })
}).then(function() {
    console.log('promise5');

    Promise.resolve().then(() => {
        console.log('promise6')
    })
}).then(() => {
    console.log('promise7')
})

好吧,这会非常冗长。与其他人相反,我会声称,执行顺序console.log调用在这里是完全确定性的。对于异步代码来说,情况并不总是如此,但是当没有发生任何“真正的”异步代码时,情况仍然经常如此。

为清楚起见,对代码进行了编号:

01 Promise.resolve().then(function() {
02     console.log('promise1');
03     
04     Promise.resolve().then(() => {
05         console.log('promise2')
06 
07         Promise.resolve().then(() => {
08             console.log('promise3')
09 
10             Promise.resolve().then(() => {
11                 console.log('promise4')
12             })
13         })
14     })
15 }).then(function() {
16     console.log('promise5');
17 
18     Promise.resolve().then(() => {
19         console.log('promise6')
20     })
21 }).then(() => {
22     console.log('promise7')
23 })

提醒:Javascript是单线程的,同一时间只能运行一个。

接下来,每一步都是代码执行,直到上下文被释放,加上由于函数返回而导致的承诺解析。一些调用被省略(例如Promise.resolve()),因为发生了什么是显而易见的。

在每个步骤的末尾,我将列出当前队列,并且已经执行comment.log来电。由于每个函数都以console.log调用,具有唯一的编号,我也将使用它们作为函数的名称。

注意:当一个函数结束时,它又会解决一个承诺,其中有空[[PromiseFulfillReactions]],我就不提了,因为这不重要。


程序开始运行...

  • 01 Promise.resolve().then(function() {被调用并入队1
  • 15 }).then(function() {因未解决的承诺而被调用(来自then在第 1 行)中,等待它解决
  • 21 }).then(() => {因未解决的承诺而被调用(来自then第 15 行),等待它解决

排队任务:[1]

已经执行的日志:[]


  • 02 console.log('promise1');执行
  • 04 Promise.resolve().then(() => {被调用并入队2
  • 返回undefined,一个非对象(当然不是then-able,不是一个promise),导致解析从返回的promisethen在第 1 行中,这又导致其[[PromiseFulfillReactions]]待执行。唯一添加的反应来自15 }).then(function() {(往上看)。这排队5.

排队任务:[2, 5]

已经执行的日志:[1]


  • 05 console.log('promise2')执行
  • 07 Promise.resolve().then(() => {被调用并入队3

排队任务:[5, 3]

已经执行的日志:[1, 2]


  • 16 console.log('promise5');执行
  • 18 Promise.resolve().then(() => {被调用并入队6
  • 返回,与上面类似,解决了从返回的承诺15 }).then(function() {, 所以就是[[PromiseFulfillReactions]]执行。这排队7

排队任务:[3, 6, 7]

已经执行的日志:[1, 2, 5]


  • 08 console.log('promise3')执行
  • 10 Promise.resolve().then(() => {被调用并入队4

排队任务:[6, 7, 4]

已经执行的日志:[1, 2, 5, 3]

为了完整起见,我将添加最后的步骤,但从这里开始就非常简单了。


  • 19 console.log('promise6')被执行

排队任务:[7, 4]

已经执行的日志:[1, 2, 5, 3, 6]


  • 22 console.log('promise7')被执行

排队任务:[4]

已经执行的日志:[1, 2, 5, 3, 6, 7]


  • 11 console.log('promise4')被执行

排队任务:[] empty!

已经执行的日志:[1, 2, 5, 3, 6, 7, 4]


程序终止。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我了解 microtask 和 Promise 时,我遇到了一个我不理解的行为 的相关文章

  • JavaScript 调用函数

    我最近一直在测试一些代码 试图更好地理解 javascript 然后我遇到了call 我无法很好地理解的功能 我有以下代码 function hi console log hi var bye function param param2 c
  • jQuery-UI 的自动完成显示效果不佳,z-index 问题

    我目前正在我的客户网上商店中实现 jQuery UI 的自动完成功能 问题是 自动完成所在的元素的 z 索引高于自动完成的 z 索引 我尝试手动设置自动完成 z index 但我感觉 jQuery UI 正在覆盖它 事实上我的问题是重复的自
  • 使用字符串函数查找周期字符串

    我正在寻找一种方法来检查字符串是否是周期性的或不使用 JavaScript 要匹配的示例字符串可以是11223331122333 然而 10101不应该匹配 来自 python 我使用了 RegEx 1 但速度相当慢 有没有任何字符串方法可
  • 如何绑定国家/地区更改国际电话输入

    我使用国家代码插件名称国际电话输入 js https intl tel input com 这是我的演示页面 在页面中我想清空手机 输入字段 当国家选择改变时 div class demo h3 Demo h3 div class iti
  • 如何在此彩票功能中显示所有猜中的号码?

    我用 JS 创建了一些简单的彩票功能 一切正常 我面临的唯一问题是如何显示所有已猜到的数字 我有 6 个独立的空间 其中必须提供数字 我的目标是显示随机空间中的滚动数字 它必须仅在 6 个空间之一中提供 这对我有用 但只显示 1 个数字 我
  • 如何通过ajax点击时从javascript文件执行节点(控制台)命令

    我是 Node js 新手 这是我的问题 例如 我得到了 Web 应用程序 并且从该应用程序中我有一个按钮 单击按钮后我想运行节点控制台命令 例如 node socket io So button on click function run
  • 尝试在 Windows 上执行 package.json 中的脚本会引发 JScript 错误

    所以我正在尝试构建 javascriptair site 在 的里面package json有一个 npm 脚本指向 javascript 命令 package scripts 找到该存储库https github com kentcdod
  • 如何在D3中导入json数据?

    如何在D3中导入json文件 I did d3 json temp json 但是我如何在进一步的代码中访问这个数据集呢 到目前为止我已经尝试过 var data d3 json temp json 但使用 data data 在其余代码中
  • CKFinder 如何在选择图像(文件:选择)时获取尺寸 URL 和尺寸(宽度/高度)?

    我正在使用 CkFinder 3 成功上传图像后 我需要能够在用户单击 选择 按钮后进行检测 文件名 ID url 原始图像的宽度和高度 目前我正在使用files choose但我找不到有关 cb 事件的信息 知道如何解决吗 代码示例将不胜
  • 为什么WAV格式在不同的浏览器中没有相同的mimetype?

    文件输入在 Chrome 或 Firefox 中为同一文件提供不同的 Mimetype 我有一个我想上传的 wav 文件 chrome 说是audio wav和火狐检测audio x wav 我知道这两个 mimetype 非常相似 x 代
  • ReactJs / Typescript:如何扩展状态接口

    我有以下内容 interface EditViewState
  • Mustache javascript:如何处理布尔值

    我有一个 JavaScript 对象obj键的值可以是true or false 该值被传递给 Mustache 模板 JavaScript 对象 obj like true or false 模板 span like span 现在我希望
  • 在 JavaScript 中给变量字符串加上引号

    我有一个 JavaScript 变量 var text http example com 文本可以是多个链接 如何在变量字符串周围放置 例如 我希望字符串看起来像这样 http example com var text http examp
  • HTML5:从存储的二进制字符串播放视频

    我正在尝试使用 FileReader readAsBinaryString Blob File 将视频文件的内容作为二进制字符串读取 如示例中所示http www html5rocks com en tutorials file dndfi
  • 带条件的 Array.join()

    我该如何使用Array join 有条件的函数 例如 var name aa bb var s name join 输出是 aa bb 我想添加一个条件 仅显示不为空的单词 aa bb 您可以使用Array filter https dev
  • 在画布中的鼠标位置放大/缩小

    我正在尝试使用 p5 js 实现缩放功能 当前缩放级别以及 x 和 y 位置存储在controls view目的 默认位置或 0 0 位置位于左上角 问题是调整放大 缩小时的 x 和 y 位置值 以便无论视图的当前位置是什么 它都会停留在缩
  • html5 canvas贝塞尔曲线获取所有点

    我喜欢从贝塞尔曲线中得到一些点 我发现 在javascript中查找三次贝塞尔曲线的所有点 https stackoverflow com questions 15397596 find all the points of a cubic
  • 如何提交表单 onkeyup 操作

    我正在尝试保存表格onkeyup行动 我是 jQuery 新手 这可能吗 我很感激任何帮助 编辑1 保存表单意味着保存到服务器 有没有办法增加0 2秒的延迟 此代码将在 keyup 上提交您的表单 element bind keyup fu
  • 在客户端将大文件(> 2GB)压缩为 ZIP

    我使用构建上传工具node js and socket io 因为他们通常会上传令人难以置信的巨大文件 而普通的上传表单将无法工作 问题是他们想在发送之前将文件压缩成zip 以提高传输效率 我一直在研究压缩方法 例如JSZip http s
  • Google Universal Analytics - 命令被忽略

    我正在使用 Google Universal Analytics 来跟踪页面浏览量 当我导航到具有 Google Analytics 网站实时功能的页面时 我可以看到 因此我的代码一定可以正常工作 然而 Chrome 一直在控制台中显示 I

随机推荐