向微队列添加任务的四种方式

向微队列添加任务的四种方式

关于微任务,微队列,事件循环,可参考:深入:微任务与 Javascript 运行时环境 - Web API 接口参考 | MDN (mozilla.org)

先说答案, 四种方法:

  1. Promise.resolve().then();
  2. MutationObserver
  3. process.nextTick();
  4. queueMicrotask()

Promise.resolve().then()

查看ECMA-262关于then方法的描述:

可知then方法会在promise状态为fulfilledrejected时将对应的任务(onFulfilledonRejected)放到任务队列中,然后注意到MDN在一篇关于微任务的文章中提到:

JavaScript 中的 promise 和 Mutation Observer API 都使用微任务队列去运行它们的回调函数

于是我们可以知道then方法的回调将会被添加到微队列中执行, 若查看V8引擎源码可进一步佐证这一点。

这样一来,我们就可以用以下代码向微队列中添加一个任务:

const task = () => {console.log("do somthing");
}
Promise.resolve().then(task);

进一步, 根据ECMA-262的描述(上图红框部分), 当promise状态为rejected时,onRejected也会被添加到微队列, 于是以下代码也可以达到相同的效果:

//以下两种方法等价
Promise.reject().then(null, task);Promise.reject().catch(task);

验证一下, 执行以下代码, 发现打印顺序符合预期:

setTimeout(() => {console.log("timeout");
}, 0);
Promise.resolve().then(() => {console.log("promise resolve");
})Promise.reject().then(null, () => {console.log("promise reject");
});Promise.reject().catch(() => {console.log("promise catch");
});
console.log("同步");//打印结果:
// 同步
// promise resolve
// promise reject
// promise catch
// timeout

MutationObserver API

同样根据上文提到的MDN的描述, 使用MutationObserver也可以达到向微队列中添加任务的目的, 结合MutationObserver的用法可以封装一个通用的函数:

    function enqueueMicroTaskByMutationObserver(task) {if (typeof task != "function") {throw "task必须为函数";}let m = new MutationObserver(task);let div = document.createElement("div");m.observe(div, {childList: true});div.innerText = "1";}

注意: nodejs环境不支持MutationObserver API, 因此这个方法只能在浏览器环境中使用

在html中运行以下代码验证, 打印顺序符合预期:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>function enqueueMicroTaskByMutationObserver(task) {if (typeof task != "function") {throw "task必须为函数";}let m = new MutationObserver(task);let div = document.createElement("div");m.observe(div, {childList: true});div.innerText = "1";}setTimeout(() => {console.log("time out");}, 0);enqueueMicroTaskByMutationObserver(() => {console.log("MutationObserver");})</script>
</body></html>

process.nextTick()

MutationObserver API相反,这个方法只能用于Node环境,根据Node文档的描述:

process.nextTick()callback 添加到 “下一个滴答队列”。在 JavaScript 堆栈上的当前操作运行完成之后,且在允许事件循环继续之前,此队列将被完全排空。

暂时可将"滴答队列"简单理解为微队列,实际上,"滴答队列"的优先级似乎比微队列更高, 观察以下代码:

setTimeout(() => {console.log("timeout");
}, 0);Promise.resolve().then(() => {console.log("promise resolve");
})process.nextTick(() => {console.log("tick");
})console.log("同步");

发现无论执行多少次, "tick"总是先于"promise resolve"打印,于是推测"滴答队列"的优先级似乎比微队列更高.

queueMicrotask

在不考虑兼容性的情况下, 应当首选这个方法, 因为这个方法就是专门用来做将微任务加入队列这件事的, 参考MDN:queueMicrotask() - Web API 接口参考 | MDN (mozilla.org)

同时, queueMicrotask在浏览器和node环境中都可以使用且用起来也是最简单的, 用法如下:

queueMicrotask(() => {console.log("do somthing");
})

如有错漏,恳请指出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/720716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Web前端入门学习】——HTML

目录 HTML简介HTML文件结构常用文本标签标题标签段落标签有序列表和无序列表表格标签 HTML属性a标签—超链接标签图片标签 HTML区块块元素与行内元素 HTML表单 HTML简介 HTML全称是Hypertext Markup Language超文本标记语言。 HTML的作用&#xff1a; 为网页提供结构&#xff…

数据库管理-第158期 Oracle Vector DB AI-09(20240304)

数据库管理158期 2024-03-04 数据库管理-第158期 Oracle Vector DB & AI-09&#xff08;20240304&#xff09;1 创建示例表2 添加过滤条件的向量近似查询示例1示例2示例3示例4示例5示例6示例7 总结 数据库管理-第158期 Oracle Vector DB & AI-09&#xff08;20240304&a…

C#插入排序算法

插入排序实现原理 插入排序算法是一种简单、直观的排序算法&#xff0c;其原理是将一个待排序的元素逐个地插入到已经排好序的部分中。 具体实现步骤如下 首先咱们假设数组长度为n&#xff0c;从第二个元素开始&#xff0c;将当前元素存储在临时变量temp中。 从当前元素的前一…

iOS 17.0 UIGraphicsBeginImageContextWithOptions 崩溃处理

在升级到iOS17后你会发现&#xff0c;之前版本运行的很好&#xff0c;这个版本突然会出现一个运行闪退。报错日志为*** Assertion failure in void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloat, BOOL)(), UIGraphics.m:410 跟踪到具体的报错位置如下所示&a…

第4章 HSA运行时

HSA运行时是一种精简的用户模式应用程序编程接口API&#xff0c;它提供了主机将计算内核启动到可用HSA代理程序所必须的接口。它可以分为两类&#xff1a;核心和扩展。HSA核心运行时API旨在支持HSA系统平台体系结构规范所需的操作&#xff0c;并且必须得到任何符合HSA的系统的支…

Java多线程导入Excel示例

在导入Excel的时候&#xff0c;如果文件比较大&#xff0c;行数很多&#xff0c;一行行读往往速度比较慢&#xff0c;为了加快导入速度&#xff0c;我们可以采用多线程的方式 话不多说直接上代码 首先是Controller import com.sakura.base.service.ExcelService; import com.s…

智慧城市中的数字孪生:数字孪生技术助力智慧城市提高公共服务水平

目录 一、引言 二、数字孪生技术概述 三、数字孪生技术在智慧城市中的应用 1、智慧交通管理 2、智慧能源管理 3、智慧环保管理 4、智慧公共安全 四、数字孪生技术助力智慧城市提高公共服务水平的价值 五、挑战与前景 六、结论 一、引言 随着信息技术的飞速发展&…

【LeetCode】升级打怪之路 Day 13:优先级队列的应用

今日题目&#xff1a; 23. 合并 K 个升序链表 | LeetCode378. 有序矩阵中第 K 小的元素 | LeetCode373. 查找和最小的 K 对数字 | LeetCode703. 数据流中的第 K 大元素 | LeetCode347. 前 K 个高频元素 | LeetCode 目录 Problem 1&#xff1a;合并多个有序链表 【classic】LC 2…

【蓝牙协议栈】【BR/EDR】【AVDTP】音视频分布传输协议

1. AVDTP概念 AVDTP即 AUDIO/VIDEO DISTRIBUTION TRANSPORT PROTOCOL(音视频分配传输协议),主要负责 A/V stream的协商、建立及传输程序,还指定了设备之前传输A/V stream的消息格式. AVDTP的传输机制和消息格式是以 RTP为基础的。RTP由 RTP Data Transfer Protocol (RTP)和…

【软考高项】【计算专题】- 5 - 进度类 - 横道图/甘特图

一、知识点 1、基本定义 甘特图(Gantt chart )又称为横道图、条状图(Bar chart)&#xff0c;通过条状图来显示项目各活动的进 度情况。以提出者亨利劳伦斯甘特( Henry Laurence Gantt)先生的名字命名。 目前许多文档工具都可以画甘特图。 &#xff08;1&#xff09;我的举例 …

07. Nginx进阶-Nginx负载均衡

简介 负载均衡 什么是负载均衡&#xff1f; 负载均衡&#xff0c;英文名称为Load Balance&#xff0c;其含义就是指将负载&#xff08;工作任务&#xff09;进行平衡、分摊到多个操作单元上进行运行。 Nginx负载均衡 什么是Nginx负载均衡&#xff1f; Nginx负载均衡可以大…

计算机网络-典型网络组网架构

前面基本网络知识已经能够满足中小企业的需要了&#xff0c;今天来看下一些基本网络组网架构。 首先网络是分层架构&#xff0c;从接入层到汇聚层再到核心层&#xff0c;然后接入运营商出口。内部包括有线网络、无线网络&#xff0c;出口一般可以使用路由器或者防火墙进行安全防…

StarRocks实战——vivo基于 StarRocks 构建实时大数据平台

目录 前言 一、数据挑战 1.1 时效性挑战&#xff0c;业务分析决策需加速 1.2 访问量挑战&#xff0c;性能与稳定性亟待提高&#xff0c;支撑业务稳定运行 1.3 计算场景挑战&#xff0c;难以满足业务复杂查询需求 1.4. 运维挑战&#xff0c;用户查询体验需优化 二、OLA…

WebDAV之π-Disk派盘+人生Life

人生Life是一款日程软件,在这款待办的日程软件当中各种功能极为的完善,完全的足够用户在日常当中的使用,你的待办方面的各种内容都能够在软件上面进行规划和填充,通过待办事项来帮助用户提高在日常当中的效率,对于用户来说这款待办事项的软件是绝佳的选择。 π-Disk派盘 …

java面试(jvm)

JVM内存模型 细分Eden&#xff1a; java类加载过程&#xff1f;双亲委派机制&#xff1f;一个对象从加载到JVM&#xff0c;再到被GC清除过程&#xff1f; JAVA类加载器&#xff1a;AppClassLoader - ExtClassLoader - BootStrapClassLoader。每种类加载器都有他自己的加载目录…

2024年聚合工艺证模拟考试题库及聚合工艺理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年聚合工艺证模拟考试题库及聚合工艺理论考试试题是由安全生产模拟考试一点通提供&#xff0c;聚合工艺证模拟考试题库是根据聚合工艺最新版教材&#xff0c;聚合工艺大纲整理而成&#xff08;含2024年聚合工艺证…

ANSYS穿孔板随机微孔隙构建及力学模拟

多孔结构板在减轻结构重量、满足吸声功能等环境下应用广泛&#xff0c;本案例采用ANSYS Workbench对曲线边界孔洞的随机多孔板进行轴心受拉力学分析。 随机微穿孔板可采用CAD Voronoi插件构建&#xff0c;三维模型构建如下。 CAD Voronoi插件采用参数化建模方式&#xff0c;根…

Mysql去除重复项:力扣182. 查找重复的电子邮箱

题目链接&#xff1a;182. 查找重复的电子邮箱 - 力扣&#xff08;LeetCode&#xff09; 题目描述 sql语句 方法1&#xff1a;使用临时表 select Email from (select Email, count(Email) as numfrom Persongroup by Email ) as statistic where num > 1 ;方法2&#xff…

树状图怎么做?这个方法教你轻松制作

树状图怎么做&#xff1f;在日常生活和工作中&#xff0c;我们经常需要用到树状图来整理和展示信息。树状图不仅能够帮助我们清晰地表达层级关系&#xff0c;还能够让复杂的数据和信息一目了然。那么&#xff0c;如何制作一个既美观又实用的树状图呢&#xff1f;本文将为你详细…

【回溯算法】【组合问题】Leetcode 77.组合 216. 组合总和 III

【回溯算法】【回溯算法剪枝】 Leetcode 77.组合 216. 组合总和 III 回溯算法可以解决的问题Leetcode 77.组合解法1 回溯法三部曲&#xff0c;函数参数、终止条件和单层搜索逻辑解法一plus 回溯法剪枝 另一道组合回溯问题 216. 组合总和 III解法&#xff1a;回溯解法&#xff1…