事件循环机制

7/18/2022 js

# 1.堆、栈、队列

堆Heap:存放引用类型

栈Stack:后进先出,执行同步任务

队列Queue:先进先出,存放异步任务 在这里插入图片描述

# 2.事件循环

js是单线程的,但是执行时会分为同步异步任务

在这里插入图片描述

在任务入执行栈时,会将异步任务推入任务队列,同步任务放入主线程中执行,待主线程空了之后再回头去按顺序执行任务队列里的异步任务,如此循环

# 3.宏任务和微任务

除了同步和异步任务,还可以更精细化可分为宏任务微任务,常见的宏任务和微任务如下:

宏任务: 普通同步代码setTimeoutsetIntervalnew promise异步ajax请求

微任务: promise.then.catch.finallyqueueMicrotaskprocess.nextTick(仅在node.js中,且享有优先执行权)

队列里面有宏任务和微任务,浏览器每次事件循环都会执行一个宏任务,和该宏任务下的所有微任务。遇到定时器等异步任务会放到异步队列等待下一轮循环。这样一直运行,只到执行栈为空和队列为空

在这里插入图片描述
console.log('1') // 同步宏

setTimeout(function() { // 异步宏
  console.log('2')
  process.nextTick(function() { // 异步微(高优先级)
    console.log('3')
  })
  new Promise(function(resolve) { // 同步宏
    console.log('4')
    resolve()
  }).then(function() { // 同步微
    console.log('5')
  })
})
// 非node.js环境忽略process.nextTick
process.nextTick(function() { // 异步微,在微任务中最高优先级
  // 即所有同步宏任务结束之后立刻执行这个异步微任务,再恢复执行同步剩下的微任务
  console.log('6') 
})
new Promise(function(resolve) { // 同步宏
  console.log('7')
  resolve()
}).then(function() { // 同步微
  console.log('8')
})

setTimeout(function() { // 异步宏
  console.log('9')
  process.nextTick(function() { // 异步微(高优先级)
    console.log('10')
  })
  new Promise(function(resolve) { // 同步宏
    console.log('11')
    resolve()
  }).then(function() { // 同步微
    console.log('12')
  })
})

// node环境: 1 7 6 8 2 4 9 11 3 10 5 12
// 浏览器环境: 1 7 8 2 4 5 9 11 12  process.nextTick仅在node环境有,这里忽略

# 参考

1.并发模型与事件循环 (opens new window)

2.这一次,彻底弄懂JS执行机制 (opens new window)

    我不想谋生,
    我想生活。
    红莲华
    x
    loading...