javaScript的宏任务与微任务总结

首先我们看一段代码

console.log('script start')

setTimeout(function () {
   console.log('setTimeout')
}, 0)

Promise.resolve()
  .then(function () {
    console.log('promiseone')
   })
   .then(function () {
      console.log('promisetwo')
   }

console.log('script end')

那执行的结果如下:

javaScript的宏任务与微任务总结_第1张图片

那我们来看一下这个执行过程:

我们都知道javascript是一个单线程的语言,我们有同步和异步两种任务 。同步任务在主线程上是一个个执行,而异步任务则会进入任务队列(Task Queue),只有在所有同步任务执行完,异步任务才会被执行,那么问题来了,那按照这个逻辑的话执行顺序应该是:

javaScript的宏任务与微任务总结_第2张图片

 那这就来到我们宏任务微任务了;在ES6 规范中,microtask 称为 jobs,macrotask 称为 task,宏任务是由宿主发起的,而微任务由JavaScript自身发起。 我们列一个表格来整理一下两者的区别

描述 宏任务(macrotask) 微任务(microtask)
发起 宿主(Node、浏览器) JS引擎
事件 1. script (可以理解为外层同步代码)
2. setTimeout/setInterval
3. UI rendering/UI事件
4. postMessage,MessageChannel
5. setImmediate,I/O(Node.js)
1. Promise
2. MutaionObserver
3. Object.observe(已废弃;Proxy 对象替代)
4. process.nextTick(Node.js)
运行顺序 后运行 先运行
是否触发新一轮Tick 不会

 那我们针对上面的代码来分析,

1首先肯定是执行script start因为是属于script中,打印出  script start

2.执行setTimeout,因为是属于异步任务同时是属于宏任务,所以会先存在宏任务队列(macrotask当中

3.执行Promise,这个属于是异步微任务,所以会先存在微任务的队列(microtask)

4.然后执行到 script的最后打印出“script end”,主线程(JS stack)被清空,这个时候同步任务就执行完了

5.主线程一旦全部执行完毕就会取清空微任务,所以接下来Microtask中的 Promise then(promise)被加入到主线程中执行,执行了回调,打印出“promise1”,同时产生了新的微任务 promise then(promise2),执行完毕后,主线程又被清空了

6.这个时候微任务队列里还有刚刚产生的 Promise then,又被加入到主线程执行打印出“promise2

7.最后的话宏任务队列里取出一个宏任务加入到主线程中执行 setTimeout callback,打印出“setTimeout

总结:如果宏任务队列和微任务队列还没清空,就会:主栈全部执行完毕后-->清空微任务-->会取出一个宏任务 --> 执行完毕后-->清空微任务 -> 无线循环,这就是我们所说的事件环(Event Loop)

你可能感兴趣的:(javascript,javascript,开发语言,ecmascript)