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. Web攻击技术---OWASP top

    整理OWASP top 10 部分内容,方便日后查看.想深入了解的,请移步参考中的网站. OWASP Top 10 注入 将不受信任的数据作为命令或者查询的一部分发送到解析器时,会发生诸如SQL注入. ...

  2. Linux系统下强制其他用户下线

    强制其他用户下线命令格式:pkill -kill -t tty 解释: pkill -kill -t 强制其他用户下线命令 tty 强制其他用户下线的TTY 如上强制其他用户下线的命令为: pkill ...

  3. Angular学习笔记【ngx-bootstrap】中的 tabset

    <tabset class="tab-container tabbable-line"> <tab heading="{{l("MobileS ...

  4. Subversion Server Edge的搭建与配置

    1.Subversion Server Edge的搭建 当在操作系统为64位的配置服务器上部署时只能够选择Collabnet Subversion Edge,它集合了Subversion所需要一切资源 ...

  5. 034 Search for a Range 搜索范围

    给定一个已经升序排序的整形数组,找出给定目标值的开始位置和结束位置.你的算法时间复杂度必须是 O(log n) 级别.如果在数组中找不到目标,返回 [-1, -1].例如:给出 [5, 7, 7, 8 ...

  6. eclipse自动添加版权信息

    Preference->Java->Code Style->Code Template->comments->Files->Edit 勾选上Automaticall ...

  7. Unity [RequireComponent(typeof(组件名))]

  8. asp.net mvc网站的发布与IIS配置

    一.安装IIS (如果服务器上已经安装了就跳过) 控制面板——程序——程序功能——打开或关闭windows功能——勾选Inertnet信息服务下面所有选项——确定 二.获取发布文件(如果已经发不好就跳 ...

  9. C#对INI文件读写

    C#本身没有对INI格式文件的操作类,可以自定义一个IniFile类进行INI文件读写. using System; using System.Collections.Generic; using S ...

  10. webpack.config.js====CSS相关:插件optimize-css-assets-webpack-plugin

    1. 安装:主要是用来压缩css文件 cnpm install --save-dev optimize-css-assets-webpack-plugin cssnano 2. webpack.con ...