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. 微信小程序 —— 微信小程序解析html富文本插件wxParse

    下载并把wxParse放到小程序的目录中 github下载地址:https://github.com/icindy/wxParse 一.基本使用方法 1. Copy文件夹wxParse,把wxPars ...

  2. 微信授权登录(OAuth2.0)-- 随记

    1.OAuth2.0简介 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户 ...

  3. 一些有关PyCharm使用总结

    目前在这里,你能看见 license server Python版本配置 添加另外版本的Python 设置字体大小 关于编码 关于模版 安装好之后,第一个问题就是 license server 问题, ...

  4. ThrowableUtil

    public class ThrowableUtil { public static Throwable getDeepestCause(final Throwable throwable) { in ...

  5. Windows开机自动登录及取消自动登录的设置

    开机自动登录 1.开始菜单搜索框输入 “netplwiz” 按回车 或“Win+R”组合键打开“运行”框内输入“netplwiz” 或“运行”框内输入“control userpasswords2”( ...

  6. Unity 碰撞的条件

  7. var obj = eval(result); 解析json

    l  var obj = eval(result);解析json

  8. c++11 多线程入门教程(一)

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/10945309.html 最近在找c++服务端开发的实习(大佬们有推荐吗QAQ..),恰好写了一 ...

  9. Spring Cloud下使用Feign Form实现微服务之间的文件上传

    背景 ​ Spring Cloud现在已经被越来越多的公司采用了,微服务架构比传统意义上的单服务架构从复杂度上多了很多,出现了很多复杂的场景.比如,我们的产品是个app,支持第三方登录功能,在手机端调 ...

  10. SVN的搭建(权限配置篇)

    如要转载,请注明出处! 两个问题: 如何维护多个目录或者仓库 目录权限如何设置 ============================================================ ...