事件循环和Promise之间有什么关系[重复]

2024-02-21

我很好奇Event Loop和Promise之间的关系。
演示暴露了这个问题。我预计p1 fulfilled出现在中间,因为它们将任务排队到同一个任务队列中并逐个执行。

var p1 = new Promise(function(resolve, reject){
    resolve(1)
})
setTimeout(function(){
  console.log("will be executed at the top of the next Event Loop")
},0)
p1.then(function(value){
  console.log("p1 fulfilled")
})
setTimeout(function(){
  console.log("will be executed at the bottom of the next Event Loop")
},0)

控制台结果是:

p1 fulfilled
will be executed at the top of the next Event Loop
will be executed at the bottom of the next Event Loop

可视化效果 http://latentflip.com/loupe/?code=dmFyIHAxID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXsKICAgIHJlc29sdmUoMSkKfSk7CnNldFRpbWVvdXQoZnVuY3Rpb24oKXsKICBjb25zb2xlLmxvZygid2lsbCBiZSBleGVjdXRlZCBhdCB0aGUgdG9wIG9mIHRoZSBuZXh0IEV2ZW50IExvb3AiKQp9LDApCnAxLnRoZW4oZnVuY3Rpb24odmFsdWUpewogIGNvbnNvbGUubG9nKCJwMSBmdWxmaWxsZWQiKQp9KQpzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7CiAgY29uc29sZS5sb2coIndpbGwgYmUgZXhlY3V0ZWQgYXQgdGhlIGJvdHRvbSBvZiB0aGUgbmV4dCBFdmVudCBMb29wIikKfSwwKQ%3D%3D!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D显示了promise.then的回调没有进入事件循环的任务队列。这是正确的?

【注意:这个问题与Promise 与 setTimeout https://stackoverflow.com/questions/38752620/promise-vs-settimeout,因为它更关注Event Loop和Promise之间的关系】


每个事件循环都有一个微任务队列和一个宏任务队列。

微任务是原本要在微任务队列而不是任务队列上排队的任务。参考https://www.w3.org/TR/html51/webappapis.html#microtask-queue https://www.w3.org/TR/html51/webappapis.html#microtask-queue.

微任务有两种:

  • 单独的回调微任务,例如Promise
  • 和复合微任务,例如Object.observe, MutationObserver and process.nextTick在 Node.js 中。

而宏任务队列主要包含setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O在 Node.js 中。

在事件循环中,这两个任务队列将分两步运行:

  1. 首先,检查旧的宏任务队列中是否存在宏任务(称之为X);
  2. 如果X存在并且正在运行,则等待它执行下一步,直到完成;否则,立即进行下一步;
  3. 其次,运行微任务队列的所有微任务;
  4. 当运行微任务时,我们仍然可以添加更多的微任务到队列中,这些任务也会运行。

在你的例子中:

  1. 首先,你的 Promise 初始化new Promise and resolve是同步的;
  2. 然后同步添加一个setTimeout将macroTask放入macrotask队列中;
  3. 然后同步添加微任务promise.then(function(){})到 microtask 队列中,该任务会立即运行,因为 Promise 的初始化和解析是同步的,该任务在任何宏任务之前运行;所以,console.logp1 fulfilled;
  4. 然后添加第二个宏任务setTimeout到宏任务队列;
  5. 事件循环结束后,运行两个宏任务;

对于这段代码:

setTimeout(function() {
  console.log("will be executed at the top of the next Event Loop")
}, 0)
var p1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve(1)
  }, 0)
});
setTimeout(function() {
  console.log("will be executed at the bottom of the next Event Loop")
}, 0)
for (var i = 0; i < 100; i++) {
  (function(j) {
    p1.then(function(value) {
      console.log("promise then - " + j)
    });
  })(i)
}

输出顺序:

will be executed at the top of the next Event Loop
promise then - 0
promise then - 1
promise then - 2
...
promise then - 99
will be executed at the bottom of the next Event Loop
  1. 首先添加三个宏任务setTimeout宏任务队列和微任务promise.then()到微任务队列;
  2. 运行宏任务;
  3. 如果条件为 true 则运行所有微任务,但为 false,则进入下一步;
  4. 运行第二个宏任务;
  5. 检查promise是否已解决,条件为真,然后运行所有微任务;
  6. 继续运行其他宏任务;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

事件循环和Promise之间有什么关系[重复] 的相关文章

  • 如何在 Angular2 中嵌入视频?

    我想开发单页应用程序 它是一个视频门户 用户可以登录 查看视频列表 导航到单个视频 对视频进行评分 并可以执行所有媒体相关任务 例如 播放 暂停 调整音量和寻找视频位置 既然有
  • 使用 Selenium 自动化结帐流程时出现 403

    我正在尝试使用 python 和 selenium 创建一个脚本来自动执行 bestbuy ca 的结帐过程 我一直到达最后阶段 您可以单击以查看最终订单 但当我尝试单击到最后一步时 收到以下 403 禁止消息 如网络响应中所示 是否有服务
  • JavaScript 调用函数

    我最近一直在测试一些代码 试图更好地理解 javascript 然后我遇到了call 我无法很好地理解的功能 我有以下代码 function hi console log hi var bye function param param2 c
  • ng-focus 发射两次而 ng-blur 从不发射

    到目前为止 我对 Angular 已经有了相当的经验 但这似乎是在较低级别上发生的 DOM 事件传播方式的事情 由于某种原因 在我的申请的一部分中 我有ng focus and ng blur一样的input 但是ng focus事件触发两
  • 停止 jQuery 循环设置 display:none;

    我正在创建一个小游戏 用户从一组项目中进行选择 然后对所选项目进行洗牌并选择一个 我正在使用 jQuery 循环 http jquery malsup com cycle http jquery malsup com cycle 运行主动画
  • jQuery-UI 的自动完成显示效果不佳,z-index 问题

    我目前正在我的客户网上商店中实现 jQuery UI 的自动完成功能 问题是 自动完成所在的元素的 z 索引高于自动完成的 z 索引 我尝试手动设置自动完成 z index 但我感觉 jQuery UI 正在覆盖它 事实上我的问题是重复的自
  • 如何阻止 HTML 输入字段中的特殊字符? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我只是想问一下如何在html输入字段中阻止 等特殊字符 为什么不使用html5呢
  • 在 ES6 Node.js 中导入“.json”扩展名会引发错误

    我们正在尝试使用 Node js 导出和导入 ES6 模块的新方法 对于我们来说 从package json文件 下面的代码应该做到这一点 import name version from package json 但是 执行时会抛出以下错
  • 如何在 Rollup 中配置从多个输入文件仅生成单个输出文件?

    配置Rollupjs生成库时 如果输入是由多个javascript文件组成的数组 我们如何才能将这些输入生成为一个输出 js 文件呢 export const lgService input src app services livegiv
  • 尝试在 Windows 上执行 package.json 中的脚本会引发 JScript 错误

    所以我正在尝试构建 javascriptair site 在 的里面package json有一个 npm 脚本指向 javascript 命令 package scripts 找到该存储库https github com kentcdod
  • JS 中的触摸板滚动检测,无库

    我正在制作自己的小型 Javascript 库 可以轻松地将您网站 和我的网站 的默认滚动条替换为自定义滚动条 其中一部分意味着为 BODY 元素提供 overflow hidden 样式来隐藏正常的滚动条 但是 这会阻止除代码中完成的滚动
  • 打开图层地图,经纬度获取地址

    我正在尝试获取带有经度和纬度的地址 城市 邮政编码 街道地址 但我不知道如何获取 我正在使用开放图层 当我单击地图的一部分时 会获取该位置的经度和纬度 有人有解决方案吗 div class map div
  • 从 PHP/Web 应用程序打印多个标签到 Dymo LabelWriter 450 Turbo

    我希望添加使用 Dymo LabelWriter 450 Turbo 打印多个标签的功能 我已经从 Dymo 网站下载了 DYMO Label v 8 SDK dmg 但看不到任何 Javascript Web 相关的 SDK 文件或文档
  • 如何在D3中导入json数据?

    如何在D3中导入json文件 I did d3 json temp json 但是我如何在进一步的代码中访问这个数据集呢 到目前为止我已经尝试过 var data d3 json temp json 但使用 data data 在其余代码中
  • jQuery:在方法上取消绑定 jQuery 2.0

    在 jQuery 1 9 中live 已被弃用 因此新方法变为 document on mouseover blahblahfunc 我无法解除 blahblahfunc 的绑定 通过 unbind mouseover mouseout c
  • Mustache javascript:如何处理布尔值

    我有一个 JavaScript 对象obj键的值可以是true or false 该值被传递给 Mustache 模板 JavaScript 对象 obj like true or false 模板 span like span 现在我希望
  • JavaScript 中 == 和 === 的区别[重复]

    这个问题在这里已经有答案了 有什么区别 and 在 JavaScript 中 我也见过 and 运营商 还有更多这样的运营商吗 看看这里 http longgoldenears blogspot com 2007 09 triple equ
  • 在 JavaScript 中给变量字符串加上引号

    我有一个 JavaScript 变量 var text http example com 文本可以是多个链接 如何在变量字符串周围放置 例如 我希望字符串看起来像这样 http example com var text http examp
  • ImmutableJS:合并两个对象列表,而不重复它们

    假设我有以下内容 var allFoods Immutable List var frenchFood Immutable List type french fries price 3 type petit gateau price 40
  • 删除鼠标悬停时的 Vue 自定义过滤器

    我想使用 VueJS 2 删除鼠标悬停时的截断过滤器 这是模板中的过滤器 div class eng word english truncate div 这是过滤器本身 filters truncate function value let

随机推荐

  • XNA 模拟 Game 对象或解耦您的 Game

    我想知道是否可以模拟 Game 对象来测试我的 Drawable Game Component 组件 我知道模拟框架需要一个接口才能运行 但我需要模拟实际的Game http msdn microsoft com en us library
  • 在 iOS 8 Beacon 中未检测到

    iBeacon 在 iOS8 中突然停止工作 之前它在之前的 iOS 8 版本中运行良好 有人帮助我摆脱这个问题吗 请问是什么问题 谢谢 您需要做的是在代码中添加访问位置服务的请求权限 如下所示 if self locationManage
  • 如何在CXF中使用PATCH方法

    我正在尝试使用 JAX RS 的 CXF 实现在我的客户端中使用 PATCH 方法 起初我将 PATCH 注释定义为 Target ElementType METHOD Retention RetentionPolicy RUNTIME H
  • C 与 C++ 中的 typedef 和 struct 命名空间

    我正在尝试在一些新的 C 中使用一些旧的 C 库 该库的头文件使用 D Hanson 的 C 接口和实现 https rads stackoverflow com amzn click com 0201498413隐藏实现的习惯用法 def
  • 将元素替换为outerHTML并立即访问新创建的元素

    我通过将 DOM 元素的内容替换为outerHTML 这个技巧有效 但我需要立即访问新创建的 DOM 元素 不幸的是元素的创建
  • 有没有办法只获取未命名的参数?

    在 JavaScript 函数中 arguments https developer mozilla org en US docs Web JavaScript Reference Functions and function scope
  • 为 ggplot2 中的两个构面组指定不同的 x-tick 标签

    我有代表两种方法结果的箱线图 每种方法都有两种验证方法和三种场景 使用 ggplot2 进行绘制 一切正常 但我想更改 x 轴刻度标签以区分每组中使用的技术类型 我使用了以下代码 data lt read csv results csv h
  • Laravel 和 Eloquent:检索相关项目时指定列

    这是以下帖子的后续帖子 Laravel 4 和 Eloquent 检索所有记录和所有相关记录 https stackoverflow com questions 21735011 laravel 4 and eloquent retriev
  • 从 iOS 服务检测屏幕开/关

    我正在开发一个作为服务在后台运行的网络监控应用程序 当屏幕打开或关闭时是否可以收到通知 来电 它通过使用以下代码存在于Android中 private void registerScreenOnOffReceiver IntentFilte
  • 使用nodejs进行heroku部署失败

    我正在尝试将本地文件推送到 heroku 并遇到以下错误 我的代码在github https github com asimkh apps tree haz 有人可以帮我吗 谢谢 heroku buildpacks set heroku n
  • 如何检测 STAMINA 模式?

    您能帮助我 如何以编程方式检测索尼设备上的 STAMINA 模式吗 我想通知用户 如果 STAMINA 打开 我的应用程序将无法正常工作 因为它阻止了 AlarmManager 并且设备在我需要时不会被唤醒 我也想知道这个 我想一个天真的方
  • Flask WTform 对多个字段进行验证

    根据两个或多个条目验证 WTform 的最佳方法是什么 IE 在下面的表格中 我想验证数据库中尚不存在具有所提供名称和地址的公司 class CompanyForm FlaskForm name StringField Company Na
  • 如何在bash中生成笛卡尔积?

    我想生成这样的文件 笛卡尔积 1 3 X 1 5 1 1 1 2 1 3 1 4 1 5 2 1 2 2 2 3 2 4 2 5 3 1 3 2 3 3 3 4 3 5 我可以使用嵌套循环来做到这一点 例如 for i in seq 3 d
  • 无法执行dex:Java堆空间 Java堆空间

    在 Eclipse IDE 中执行 Web 驱动程序脚本时 出现 Unable toexecute dex Java heap space Java heap space 错误 我已经使用 Android SDK 和 AVD Manager
  • Java 流压缩两个列表

    我有一个人员哈希集 一个人有名字 姓氏和年龄 例如 Person Hans Man 36 我的任务是获取 17 岁以上人员的列表 按年龄对他们进行排序 并将名字与姓氏连接起来 比如 汉斯 曼 另一个名字 另一个名字 我刚刚被允许导入 imp
  • 禁用 Reactjs 中的依赖下拉选项

    我正在制作一个简单的反应应用程序 其中有一些下拉列表 其中一个依赖于另一个 gt 这里下拉菜单 1 的值为游戏类型 例如Indoor and Outdoor gt 这里下拉菜单 2 的值为运动类型 例如Chess Tennis and Fo
  • “perf stat”输出是什么意思?

    I use perf stat 命令对一些事件进行统计 root root test perf stat a e r81d0 r82d0 v a r81d0 71800964 1269047979 1269006431 r82d0 2665
  • Graphics.Drawstring 在 PictureBox 中看起来不错,但在 Bitmap 中却很糟糕

    我正在尝试使用DrawString将文本写为图像 然后将其旋转 90 度 它无论是在位图上还是直接在 PictureBox 上都可以正常工作 但最大的区别在于质量 这PictureBox绘制的文本质量很好而且看起来很漂亮 当我把它画在图像上
  • 使用 jimp 在 Node.js 中调整图像大小并获取新图像的路径

    我正在使用 jimp 调整 node js 中的图像大小 我成功地降低了图像质量 但有点困惑如何获取新图像的路径 Jimp read test jpg function err test if err throw err test resi
  • 事件循环和Promise之间有什么关系[重复]

    这个问题在这里已经有答案了 我很好奇Event Loop和Promise之间的关系 演示暴露了这个问题 我预计p1 fulfilled出现在中间 因为它们将任务排队到同一个任务队列中并逐个执行 var p1 new Promise func