宏任务/微任务

首先,JavaScript是一个单线程的脚本语言。

微任务与宏任务的概念

  • 宏任务:当前调用栈中执行的代码成为宏任务。(主代码快,定时器等等)。
  • 微任务: 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。(promise.then,proness.nextTick等等)。
  • 宏任务中的事件放在callback queue中,由事件触发线程维护;微任务的事件放在微任务队列中,由js引擎线程维护。

运行机制

  1. 在执行栈中执行一个宏任务。
  1. 执行过程中遇到微任务,将微任务添加到微任务队列中。

  2. 当前宏任务执行完毕,立即执行微任务队列中的任务。

  3. 当前微任务队列中的任务执行完毕,检查渲染,GUI线程接管渲染。

  4. 渲染完毕后,js线程接管,开启下一次事件循环,执行下一次宏任务(事件队列中取)。

微任务:

process.nextTick
MutationObserver
Promise.then

process.nextTick > Promise.then > MutationObserver // 优先级

宏任务:

```js
script
I/O
setTimeout()
setInterval()
setImmediate()
// setImmediate 回调函数
requestAnimationFrame

主代码块 > setImmediate > MessageChannel > setTimeout / setInterval  // 优先级
```

注: 首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里

示例一

console.log('代码块')

 setTimeout(function(){
     console.log('定时器开始啦')
 });

 new Promise(function(resolve){
     console.log('马上执行for循环啦');
     resolve()
 }).then(function(){
     console.log('执行then函数啦')
 });

 console.log('代码执行结束');
首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里

遇到 new Promise直接执行,打印"马上执行for循环啦"

遇到then方法,是微任务,将其放到微任务的【队列里】

打印 "代码执行结束"

本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数, 打印"执行then函数啦"

到此,本轮的event loop 全部完成。


下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦"

   转载规则


《宏任务/微任务》 echo丶若梦 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
Event Loop 事件循环 Event Loop 事件循环
JS为什么是单线程的?最初设计JS是用来在浏览器验证表单操控DOM元素的是一门脚本语言,如果js是多线程的那么两个线程同时对一个DOM元素进行了相互冲突的操作,那么浏览器的解析器是无法执行的。 JS为什么需要异步?如果JS中不存在异步,只能
2019-11-07
下一篇 
ES2019 的新特性 ES2019 的新特性
JavaScript 不断演变,每次迭代都会得到一些新的内部更新。让我们来看看 ES2019 有哪些新的特性,并加入到我们日常开发中: Array.prototype.flat()Array.prototype.flat() 递归地将嵌套数
2019-11-06 echo丶若梦
  目录