JS事件循环之宏任务和微任务

首先我们知道javascript是一个单线程的脚本语言,也就是说我们在执行代码的过程中不会出现同时进行两个进程(执行两段代码)。

JS 执行过程中会产生两种任务,分别是:同步任务和异步任务。

  • 同步:一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去。

比如声明语句、for、赋值等,读取后依据从上到下从左到右,立即执行。

  • 异步:进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。

比如ajax网络请求,setTimeout 定时函数等都属于异步任务。异步任务会通过任务队列(Event Queue)的机制(先进先出的机制)来进行协调。

任务队列(Event Queue)

任务队列中任务分为两种

  • 宏任务,主要包括script(JS整体代码)、setTimeout、setInterval、setImmediate、I/O

  • 微任务,主要包括Promise、process.nextTick(node.js)

任务(代码) 宏/微任务 环境
script 宏任务 浏览器
事件 宏任务 浏览器
网络请求ajax 宏任务 浏览器
setTimeout 宏任务 浏览器/node
setImmediate 宏任务 node
Promise.then() 微任务 浏览器/node
process.nextTick 微任务 node
任务队列的执行过程是

先执行一个宏任务,执行过程中如果产出新的宏/微任务,就将他们推入相应的任务队列,之后在执行一队微任务,之后再执行宏任务,如此循环。以上不断重复的过程就叫做 Event Loop(事件循环)。

console.log('script start')

new Promise((resolve, reject) => {
  console.log('promise1')

 resolve('promise2')

}).then((res) => {

 console.log(res)

}).then((res)=> {

console.log('promise3')
})

setTimeout(() => {

 console.log('setTimeout')

})

console.log('script end')

结果是:

  • script start
  • promise1
  • script end
  • promise2
  • promise3
  • setTimeout

1.宏任务:执行整体代码(相当于<script>中的代码)

  1. 输出:script start
  2. 遇到 promise,输入promise1,直接resolve, 将then加入微任务,当前微任务队列promise 1。
  3. 遇到 setTimeout,加入宏任务队列,当前宏任务队列(setTimeout)
  4. 输出:script end

2.微任务:执行微任务队列(promise2)

  1. 输出:promise1,then之后产生一个微任务,加入微任务队列,当前微任务队列(promise2)
  2. 执行then,输出promise2
  3. 再执行then,输出promise3
    4.微任务队列清空。

3.宏任务:执行setTimeout

1.输出:setTimeout

posted @ 2022-10-24 17:08  像鱼灵活的猫  阅读(494)  评论(0编辑  收藏  举报