Java教程

JavaScript的事件循环(宏任务与微任务)

本文主要是介绍JavaScript的事件循环(宏任务与微任务),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

JavaScript是一门单线程语言,所以在同一时间都只有一个任务在执行,其异步操作时通过事件循环机制来实现的,其中异步操作又分为宏任务和微任务:

宏任务微任务
scriptprocess.nextTick
setTimeout、setIntervalPromise.then/catch/finally
I/O

大体上这些任务的执行顺序为主线程—>微任务—>宏任务,执行过程中有三个部分组成,分别是执行栈、宏任务队列(消息队列)和微任务队列,流程图如下图所示:

请添加图片描述

简单来说就是js先顺序执行,遇到函数则将其压入执行栈执行,执行完毕后弹出,遇到宏任务时先将其入队到宏任务队列(消息队列),等执行栈为空时将其出队并压入执行栈执行,而遇到微任务时,就将其入队到微任务队列,还是等执行栈为空时候才将其出队并压入执行栈执行,区别在于,微任务的优先级更高,只有微任务队列完全为空时,才会去处理宏任务队列。现在有下面一段代码:

var p = new Promise(resolve => {
  console.log(4)
  resolve(5)
})

function func1(){
  console.log(1)
}

function func2(){
  setTimeout(()=>{
    console.log(2)
  })
  func1()
  console.log(3)
  p.then(resolved => {
    console.log(resolved)
  }).then(()=>{
    console.log(6)
  })
}
func2()

按照上述思路来看,首先Promise是一个普通的构造函数(Promise.then才是微任务,不要搞混了),将他压入执行栈中执行,输出4;下一个是执行func2(),将其压入执行栈中,看到里面遇到了宏任setTimeout,将其入队到宏任务队列,接着将func1()压入执行栈执行,输出1,接着输出3,然后遇到两个微任务.then,将其先后入队到微任务队列中,至此func2()执行完毕,弹出执行栈。此时执行栈为空,而微任务队列中有任务,将其先后压入执行栈中执行,先后打印5和6,最后弹出执行栈,微任务队列和执行栈都为空,开始处理宏任务队列,输出2。最后,得到输出顺序为4、1、3、5、6、2。

要注意的是,如果宏任务中产生了微任务,那当前宏任务执行后就要马上处理并清空微任务队列,总而言之记住主线程—>微任务—>宏任务的执行顺序就可以了。
推荐一个视频,讲得很清楚:2分钟了解 JavaScript Event Loop | 面试必备

这篇关于JavaScript的事件循环(宏任务与微任务)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!