JS MarcoTasks MicroTasks
JS MarcoTasks MicroTasks
在JS的event loop
中,有两种任务队列microtasks
和macrotasks
microtasks
- process.nextTick
- Promise
- Object.observe
- MutationObserver
macrotasks
- setTimeout
- setInterval
- setImmediate
- I/O(Ajax, fs)
- UI渲染
在一个事件循环event loop的周期中,一个task应该从macrotask队列开始执行。当这个macrotask结束后,所有的microtasks将在同一个cycle中执行。
且在microtasks执行时还可以加入更多的microtask,然后一个一个的执行,直到microtask队列清空。
console.log('start')
const interval = setInterval(() => {
console.log('setInterval')
}, 0)
setTimeout(() => {
console.log('setTimeout 1')
Promise.resolve()
.then(() => {
console.log('promise 3')
})
.then(() => {
console.log('promise 4')
})
.then(() => {
setTimeout(() => {
console.log('setTimeout 2')
Promise.resolve()
.then(() => {
console.log('promise 5')
})
.then(() => {
console.log('promise 6')
})
.then(() => {
clearInterval(interval)
})
}, 0)
})
}, 0)
Promise.resolve()
.then(() => {
console.log('promise 1')
})
.then(() => {
console.log('promise 2')
})
event loop1:
macrotasks: [主程序代码]
microtasks: []
执行macrotasks队列,也即执行主程序代码,收集macro或micro的tasks
输出: 'start'
收集的macrotasks(下次循环的): [setInterval, setTimeout]
收集的microtasks(当前循环的): [Promise]
macrotasks队列执行完毕,这时候microtasks: [Promise]不为空,执行microtasks队列
输出: 'promise1'
输出 : 'promise2'
这时候microtasks为空
下次循环开始之前的队列状态
macrotasks: [setInterval, setTimeout]
microtasks: []
event loop2:
执行macrotasks队列
执行setInterval
输出:'setInterval',且收集setInterval到下次循环的macrotasks中
执行setTimeout
输出:'setTimeout 1',且收集Promise到当前循环的microtasks: [Promise]
由于当前循环的microtasks不为空,执行队列中的任务Promise
输出:'promise3'
输出: 'promise4'
收集setTimeout到下次循环的macrotasks中
这时候microtasks为空
下次循环开始之前的队列状态
macrotasks: [setInterval, setTimeout]
microtasks: []
event loop3:
执行macrotasks队列
执行setInterval
输出: 'setInterval',且收集setInterval到下次循环的macrotasks: [setInterval]中
执行setTimeout
输出: 'setTimeout2',且收集Promise到当前的microtasks: [Promise]
由于当前循环的microtasks不为空,执行队列中的任务Promise
输出: 'promise5'
输出: 'promise6'
清除定时器clearInterval,所以下次循环的macrotasks的setInterval被清除
下次循环开始之前的队列状态
macrotasks: []
microtasks: []
event loop4:
由于macrotasks为空,和microtasks为空,程序处于等待状态。
上面程序总的输出结果是
// event loop1
start
promise 1
promise 2
// event loop2
setInterval
setTimeout 1
promise 3
promise 4
// event loop3
setInterval
setTimeout 2
promise 5
promise 6
总结
- 一个循环开始的时候microtasks(大多情况)是空的,或者说当前循环的microtasks一开始是空的,在macrotasks执行完后可能不为空
- microtasks要等到macrotasks队列执行完毕才会开始执行,且microtasks的任务在执行的过程中,是可以添加任务的,只要当前循环还未结束
- 在当前循环中收集的macro任务是收集到下一个循环的macrotasks,而当前循环收集的micro任务是收集到当前microtasks中
最新文章
- 创业方向:O2O及移动社交 from 沈博阳
- .Net 揭密--JIT怎样运行你的代码
- 在Hadoop分布式文件系统的索引和搜索
- mysql之union
- angularJS--神奇的$scope
- DataTables获取表单输入框数据
- CSS3之背景色渐变
- Computational Geometry Template
- poj3642 Charm Bracelet(0-1背包)
- java 线程关闭小结(转)
- JS模式--装饰者模式(用AOP动态改变函数的参数)
- sed命令详解-应用篇
- 【JAVA零基础入门系列】Day3 Java基本数据类型
- Django中Form的基本使用
- router-link 返回上页 和 新窗口打开链接
- Flannel网络插件配置
- HTML 滚动条样式修改
- epoll的高效实现原理
- CVTE笔试题
- scala实现相邻两个元素挑换位置的代码,哈哈
热门文章
- python模块之datetime方法详细介绍
- eclipse链接Hadoop集群时报错Error:Call From xxx/xxx.xxx.xxx.xxx to hostname1:9000 failed on connection exception
- 【Linux】linux下vi命令大全
- 修改response,报错Cannot call getWriter(), getOutputStream() already called
- Response.Redirect 打开新窗口的两种方法
- mybatis-plus 异常 Invalid bound statement (not found)
- 如何配置阿里Maven镜像
- 彻底解决Android 应用方法数不能超过65K的问题
- elasticSearch 分布式安装
- ArcGIS10.1的安装问题