JavaScript的宏任务与微任务

一、同步任务与异步任务

首先,我们需要搞清楚同步任务和异步任务的概念以及工作原理。

同步任务

同步任务指的是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。

异步任务

异步任务指的是刚开始不进入主线程,当主线程的任务执行完了之后再调用异步任务,异步任务任务才会进入主线程执行。(setTimeout, setInterval,promise,process.NextTick)

工作原理
  • 同步和异步任务分别进入不同的执行”场所”,同步的进入主线程,异步的进入Event Table并注册函数。
  • 当指定的事情完成时,Event Table会将这个函数移入Event Queue。
  • 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

NYQKxA.png

二、宏任务与微任务

除了广义的同步任务和异步任务,我们对任务有更精细的定义。

宏任务(macro-task)

包括整体代码script,setTimeout,setInterval。

微任务(micro-task)

Promise,process.nextTick。

注意:不同类型的任务会进入对应的Event Queue,也就是说微任务会进入微任务的Event Queue,宏任务会进入宏任务的Event Queue。比如setTimeoutsetInterval会进入相同的Event Queue。

工作原理

如下示例:

1
2
3
4
5
6
7
8
9
10
11
setTimeout(function() {
console.log('setTimeout');
})

new Promise(function(resolve) {
console.log('promise');
}).then(function() {
console.log('then');
})

console.log('console');
  • 这段代码作为宏任务,进入主线程。
  • 先遇到setTimeout,为异步的宏任务,那么将其回调函数注册后分发到宏任务Event Queue。
  • 接下来遇到了Promisenew Promise立即执行,then函数为异步的微任务,分发到微任务Event Queue。
  • 遇到console.log(),立即执行。
  • 整体代码script作为第一个宏任务执行结束,看看有哪些微任务?我们发现了then在微任务Event Queue里面,执行。
  • ok,第一轮事件循环结束了,我们开始第二轮循环,当然要从宏任务Event Queue开始。我们发现了宏任务Event Queue中setTimeout对应的回调函数,立即执行。
  • 结束。

点击查看原文