JavaScript中的异步 macrotask 和 microtask
看过很多setTimeout、Promise执行顺序的面试题,一直不明白为啥都是异步操作,Promise就牛×些呢?直到了解了macrotask和micromask才恍然大悟...
先来一道面试题助助兴:
setTimeout(()=>{
console.log('A');
},0);
var obj={
func: function () {
setTimeout(function () {
console.log('B')
},0);
return new Promise(function (resolve) {
console.log('C');
resolve();
})
}
};
obj.func().then(function () {
console.log('D')
});
console.log('E');
// 结果:C、E、D、A、B
我们都知道JavaScript是一门单线程的语言,这也就意味着 JS 无法进行多线程编程,但是 JS 当中却有着无处不在的异步概念 。要完全理解异步,就需要了解 JS 的运行核心——事件队列(Event Loop)。实际上,JS代码执行都处于事件循环里。事件循环发现有异步事件发生,就把这个任务放到事件队伍中。
事件队列是一个存储着待执行任务的队列,直白点说就是:我们把每一次的异步操作(setTimeout、onclick、oninput事件、Promise...)当做一个异步任务,每进行一次异步操作,就把这个异步任务放入到异步事件的队列中,直到主线程任务执行完毕,然后开始异步的事件队列里的任务按顺序执行。
Macrotasks和Microtasks
Macrotasks和Microtasks 都属于上述的异步任务中的一种,他们分别有如下API:
macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks: process.nextTick, Promise, MutationObserver
异步任务队列分为 macrotasks 和 microtasks, 在每一次事件循环中,macrotask只会提取一个执行,而microtask会一直提取,直到microsoft队列为空为止。也就是说如果某个microtask任务被推入到执行中,那么当主线程任务执行完成后,会循环调用该队列任务中的下一个任务来执行,直到该任务队列到最后一个任务为止(microtasks优于macrotasks执行)。而事件循环每次只会入栈一个macrotask,主线程执行完成该任务后又会检查microtasks队列并完成里面的所有任务后再执行macrotask的任务。
弄清楚了这条规则后,再来分析上面的面试题就小菜一碟了。
参考文章:
https://juejin.im/post/5bac87b6f265da0a906f78d8
http://ju.outofmemory.cn/entry/349456
JavaScript中的异步 macrotask 和 microtask的更多相关文章
- javascript中的异步 macrotask 和 microtask 简介
javascript中的异步 macrotask 和 microtask 简介 什么是macrotask?什么是microtask?在理解什么是macrotask?什么是microtask之前,我们先 ...
- 【JS】336- 拆解 JavaScript 中的异步模式
点击上方"前端自习课"关注,学习起来~ JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS ...
- 【JS】285- 拆解 JavaScript 中的异步模式
JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS.我最初接触不同的异步模式时,曾想当然的觉得 promise ...
- [技术翻译]在现代JavaScript中编写异步任务
本周再来翻译一些技术文章,本次预计翻译三篇文章如下: 04.[译]使用Nuxt生成静态网站(Generate Static Websites with Nuxt) 05.[译]Web网页内容是如何影响 ...
- JavaScript中的异步函数
JavaScript中的异步函数 ES8 的 async/await 旨在解决利用异步结构组织代码的问题.为此, ECMAScript 对函数进行了扩展,为其增加了两个新关键字: async 和 aw ...
- Javascript中的异步
在C#,Java中,异步方法,通常是伴随多线程,并发等术语一起出现的,比如C#中的async方法,是运行在一个线程池线程上,并且在异步方法运行完成后,有一个回调函数通知主线程. 那么由于Javascr ...
- javaScript中的异步编程模式
1.事件模型 let button = document.getElementById("my-btn"); button.onclick = function(event) { ...
- javascript中的异步编程
正常情况下js都是顺序执行的,但是也有很多场景下实际上是异步操作: 1.定时器都是异步操作 2.事件绑定都是异步操作 3.AJAX中一般我们都采取异步操作(也可以同步) 4.回调函数可以理解为异步(不 ...
- 通过一道笔试题浅谈javascript中的promise对象
因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...
随机推荐
- Linux中VMware虚拟机增加磁盘空间的扩容操作
用VMwareware虚拟机安装的Red Hat Enterprise Linux系统剩余空间不足,造成软件无法正常安装.如果重新装一遍系统就需要重新配置好开发环境和软件的安装配置.通过上网搜集的资料 ...
- Web开发工具箱
1.打印1 Web打印组件jatoolsPrinter 2.打印2Lodop 3.web前端利器 Web Essentials
- c# ref与out的区别
c# ref与out的区别 相同点:都是输出参数 不同点: ref: 1.必须初始化,即:必须赋初始值: 2.有进有出: 3.用在需要被调用的方法修改调用者的引用的时候. 4.是传递参数的地址 o ...
- 【题解】 UOJ #2. 【NOI2014】起床困难综合症
传送门 不是很简单? 考虑一下这个数的二进制位是什么,要么是1,要么是0. 然后怎么做? 因为一开始可以选0~m的数,那么二进制为中全是0的肯定是可以选的. 接着考虑全是1的怎么选? 如果全都是1的而 ...
- Weekly Contest 121
984. String Without AAA or BBB Given two integers A and B, return any string S such that: S has leng ...
- spring 为什么可以一统江湖
spring 为什么可以一统江湖 Inversion of Contro 简称IOC 是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.也就是面向接口编程的思想. 简单的说就是使用配 ...
- 2个list取交集
list操作 element in a list and element in other list,元素在一个list,且在另一个list 在数据量大的时候使用set,把list转为集合,此方法适合 ...
- LoadRunner12_脚本中运行JavaScript
版权声明:本文为博主原创文章,未经博主允许不得转载. [系统及软件配置] LR版本:12.53 JDK版本:1.8 函数:web_js_run,该函数仅在LR12版本提供支持,LR11不支持JavaS ...
- 如何实现 Python 中 selnium 模块的换行
如何实现 Python 中 selnium 模块的换行 三种方法: 直接调用 .submit() 方法,常使用在用户密码登录中 # driver.find_element_by_xpath('//*[ ...
- Linux 下安装 resync 介绍
Linux 下安装 resync 介绍 这是官网,找到对应版本的下载地址. 这里提供Linux_X64的安装包 wget '' https://download-cdn.resilio.com/sta ...