事件循环机制
NOxONE 7/18/2022 js
# 1.堆、栈、队列
堆 Heap:存放引用类型
栈 Stack:后进先出
,执行同步
任务
队列 Queue:先进先出
,存放异步
任务
# 2.事件循环
js 是单线程的,但是执行时会分为同步
和异步
任务
在任务入执行栈时,会将异步任务推入任务队列
,同步任务放入主线程中执行,待主线程空了之后再回头去按顺序执行任务队列里的异步任务,如此循环
# 3.宏任务和微任务
除了同步和异步任务,还可以更精细化可分为宏任务
和微任务
,常见的宏任务和微任务如下:
宏任务: 普通同步代码
,setTimeout
,setInterval
,new promise
,异步ajax请求
微任务: promise.then.catch.finally
,queueMicrotask
,process.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环境有,这里忽略