JS MarcoTasks MicroTasks

在JS的event loop中,有两种任务队列microtasksmacrotasks

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中

JS MarcoTasks MicroTasks的更多相关文章

  1. 浅析Node.js的Event Loop

    目录 浅析Node.js的Event Loop 引出问题 Node.js的基本架构 Libuv Event Loop Event Loop Phases Overview Poll Phase The ...

  2. js事件循环机制 (Event Loop)

    一.JavaScript是单线程单并发语言 什么是单线程 主程序只有一个线程,即同一时间片断内其只能执行单个任务. 为什么选择单线程? JavaScript的主要用途是与用户互动,以及操作DOM.这决 ...

  3. 定时器setTimeout()和Node.js的Event Loop

    一.定时器 setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行.它在"任务队列"的尾部添加一个事件,因此要等到同步任务和 ...

  4. JavaScript:再谈Tasks和Microtasks

    JavaScript是单线程,也就是说JS的堆栈中只允许有一类任务在执行,不可以同时执行多类任务.在读js文件时,所有的同步任务是一条task,当然了,每一条task都是一个队列,按顺序执行.而如果在 ...

  5. $nextTick 宏任务 微任务 macrotasks microtasks

    1.nextTick调用方法 首先看nextTick的调用方法: https://cn.vuejs.org/v2/api/#Vue-nextTick // 修改数据 vm.msg = 'Hello' ...

  6. js经典试题之ES6

    js经典试题之ES6 1:在ECMAScript6 中,Promise的状态 答案:pending  resolved(fulfilled) rejected 解析: Promise对象只有三种状态: ...

  7. 优化js的执行

    避免使用setTimeout和setInterval进行视觉更新操作;使用 requestAnimationFrame. 将长时间运行的JavaScript 从主线程转移到 Web Workers. ...

  8. event loop js事件循环 microtask macrotask

    转: 原文 http://blog.csdn.net/sjn0503/article/details/76087631 ---------------------------------------- ...

  9. BAT 前端开发面经 —— 吐血总结 前端相关片段整理——持续更新 前端基础精简总结 Web Storage You don't know js

    BAT 前端开发面经 —— 吐血总结   目录 1. Tencent 2. 阿里 3. 百度 更好阅读,请移步这里 聊之前 最近暑期实习招聘已经开始,个人目前参加了阿里的内推及腾讯和百度的实习生招聘, ...

随机推荐

  1. CCF201612-1 中间数(二分思想)

    问题链接:CCF201612试题. .对n个数进行排序,找出中间那个数,然后将中间那个数的左右与其相等的数去掉,看左右剩下的数个数是否相等,如果相等则中间那个数就是答案,否在输出-1. 问题描述 问题 ...

  2. BZOJ 1500 [NOI2005]维修数列 FHQ Treap

    终于A了这题...这题还是很好...但是我太菜...重构了三遍qwq FHQ Treap大法好!qwq...~~ Ins:直接拿输入造一棵树,把原来的树split成[1,pos],[pos+1,n], ...

  3. 查询rabbitmq

    package com.yunda.app.service; import java.io.InputStream; import java.net.HttpURLConnection; import ...

  4. bootstrap multiselect的使用 多选下拉菜单

    官网网址: http://davidstutz.de/bootstrap-multiselect/

  5. 关于jetty的那些奇葩问题

    Jetty的解压目录并不像Tomcat那样直接是在webapps下,如果你什么都不做修改的话,Ubuntu14.04下Jetty的默认解压目录是/var/cache/jetty/data/下: 比如我 ...

  6. 四,JVM 自带工具之jvisualvm

    http://www.ibm.com/developerworks/cn/java/j-lo-visualvm/index.html?ca=drs- https://visualvm.java.net ...

  7. Storm概念学习系列之什么是实时流计算?

    不多说,直接上干货! 什么是实时流计算?    1.实时流计算背景 2.实时计算应用场景 3.实时计算处理流程 4.实时计算框架 什么是实时流计算? 所谓实时流计算,就是近几年由于数据得到广泛应用之后 ...

  8. pat1061. Dating (20)

    1061. Dating (20) 时间限制 50 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Sherlock Holmes ...

  9. Unity C# Sting.Format的学习

    String.Format (String, Object) 将指定的 String 中的格式项替换为指定的 Object 实例的值的文本等效项. String.Format (String, Obj ...

  10. 前端-页面性能调试:Hiper

    前端-页面性能调试:Hiper   我们写单页面应用,想看页面修改后性能变更其实挺繁琐的.有时想知道是「正优化」还是「负优化」只能靠手动刷新查看network.而Hiper很好解决了这一痛点(其实Hi ...