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中
JS MarcoTasks MicroTasks的更多相关文章
- 浅析Node.js的Event Loop
目录 浅析Node.js的Event Loop 引出问题 Node.js的基本架构 Libuv Event Loop Event Loop Phases Overview Poll Phase The ...
- js事件循环机制 (Event Loop)
一.JavaScript是单线程单并发语言 什么是单线程 主程序只有一个线程,即同一时间片断内其只能执行单个任务. 为什么选择单线程? JavaScript的主要用途是与用户互动,以及操作DOM.这决 ...
- 定时器setTimeout()和Node.js的Event Loop
一.定时器 setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行.它在"任务队列"的尾部添加一个事件,因此要等到同步任务和 ...
- JavaScript:再谈Tasks和Microtasks
JavaScript是单线程,也就是说JS的堆栈中只允许有一类任务在执行,不可以同时执行多类任务.在读js文件时,所有的同步任务是一条task,当然了,每一条task都是一个队列,按顺序执行.而如果在 ...
- $nextTick 宏任务 微任务 macrotasks microtasks
1.nextTick调用方法 首先看nextTick的调用方法: https://cn.vuejs.org/v2/api/#Vue-nextTick // 修改数据 vm.msg = 'Hello' ...
- js经典试题之ES6
js经典试题之ES6 1:在ECMAScript6 中,Promise的状态 答案:pending resolved(fulfilled) rejected 解析: Promise对象只有三种状态: ...
- 优化js的执行
避免使用setTimeout和setInterval进行视觉更新操作;使用 requestAnimationFrame. 将长时间运行的JavaScript 从主线程转移到 Web Workers. ...
- event loop js事件循环 microtask macrotask
转: 原文 http://blog.csdn.net/sjn0503/article/details/76087631 ---------------------------------------- ...
- BAT 前端开发面经 —— 吐血总结 前端相关片段整理——持续更新 前端基础精简总结 Web Storage You don't know js
BAT 前端开发面经 —— 吐血总结 目录 1. Tencent 2. 阿里 3. 百度 更好阅读,请移步这里 聊之前 最近暑期实习招聘已经开始,个人目前参加了阿里的内推及腾讯和百度的实习生招聘, ...
随机推荐
- day14内置函数作业详解
day14题目 day14作业及默写 1,整理今天所学内容,整理知识点,整理博客. 2,画好流程图. 3,都完成的做一下作业(下面题都是用内置函数或者和匿名函数结合做出): 4,用map来处理字符串列 ...
- python大战机器学习——模型评估、选择与验证
1.损失函数和风险函数 (1)损失函数:常见的有 0-1损失函数 绝对损失函数 平方损失函数 对数损失函数 (2)风险函数:损失函数的期望 经验风险:模型在数据集T上的平均损失 根据大 ...
- spring框架详细课程视频
https://ke.qq.com/course/27346#term_id=100012852
- (转)Linux命令学习总结:dos2unix - unix2dos
Linux命令学习总结:dos2unix - unix2dos 命令简介: 原文:http://www.cnblogs.com/kerrycode/p/5077969.html dos2unix是将W ...
- js里的数组push用法及append()
result.result[0].name var arr = new Array();$.each(result.result, function(i, item) { arr ...
- java里如何实现对数组中的元素反转[4, 1, 8, 7, 3, 8, 2]变成 [2, 8, 3, 7, 8, 1, 4]
不多说,直接上干货! 给定一个数组,对其进行反转. {3,1,6,5,8,2} --> {2,8,5,6,1,3}; 其实就是头尾元素的位置置换. package zhouls.bigdata. ...
- placeholder-shown
一般我们常见placeholder伪类选择器用来修改默认样式及文案,忽然发现placeholder-shown伪类选择器,比较官方的解释是 CSS伪类表示任何显示占位符文本的form元素. 简单来说就 ...
- HDU 2586——How far away ?——————【LCA模板题】
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 如何下载Oracle E-Business Suite (12.2.6) for Microsoft Windows x64 (64-bit)
下载地址:https://edelivery.oracle.com/ 使用您的 Oracle 账户进行登录.如果您没有该账户, 请注册 Oracle 账户. Oracle Software D ...
- web安全防御之RASP技术
作者: 我是小三 博客: http://www.cnblogs.com/2014asm/ 由于时间和水平有限,本文会存在诸多不足,希望得到您的及时反馈与指正,多谢! 0x00:we ...