基本知识
js是单线程的,只有一个主线程处理逻辑
事件循环的作用
保证主线程, 有序并高效 或非阻塞 的处理
在js事件中主要分为同步事件(同步任务)与异步事件(异步任务)
同步事件
在主线程中执行的任务
异步事件
只有主线程的执行栈为空时才开始执行异步任务,异步任务又可进一步分为宏任务与微任务
宏任务与微任务的分类
宏任务:
- script(整体代码)
- setTimeout
- setInterval
- setImmediate
- I/O
- UI render
微任务:
- process.nextTick
- Promise
- Async
- MutationObserver
事件循环运行机制
- 首先执行同步代码,遇到宏任务将其加入宏任务队列,遇到微任务(微任务中又存在微任务会将其就加入到微任务队列的队尾)将其加入微任务队列,直到主线程执行栈为空
- 检查是否存在微任务,有则会执行至微任务队列为空,然后执行下一个宏任务
- 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
事件循环执行循序
-
算上script(整体代码)宏任务,因当前主线程执行栈为空,script(整体代码)中的事件会立即加入到主线程中执行
动手试一试
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
return Promise.resolve().then(()=>{
console.log('async2 end1')
})
}
async1()
setTimeout(function() {
console.log('setTimeout1')
setTimeout(function() {
console.log('setTimeout3')
}, 0)
new Promise(resolve => {
resolve()
}).then(function() {
console.log('promise3')
})
.then(function() {
console.log('promise4')
})
}, 0)
setTimeout(function() {
console.log('setTimeout2')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
setTimeout(()=>{
console.log("123456")
},0)
})
new Promise(resolve=>{
resolve()
}).then(()=>{
console.log('456789')
})
console.log('script end')