| 主线程 |  | 
| 微队列 | 微队列任务1, 微队列任务2 | 
| 延时队列 | 延时队列任务1, 延时队列任务2 | 
| 交互队列 | .... | 
事件循环的工作原理
-  主线程执行同步任务: - 主线程首先执行所有同步任务(即栈中的任务)。这些任务会按顺序执行,直到没有更多同步任务为止。
 
-  遇到微任务或宏任务: - 在执行同步任务时,如果遇到异步任务(例如 Promise、setTimeout等),这些异步任务会被添加到相应的队列中。具体来说:- 微任务(Microtask):如 Promise.then()、MutationObserver等会被加入到微任务队列中。
- 宏任务(Macrotask):如 setTimeout、setInterval、I/O操作等会被加入到宏任务队列中。
 
- 微任务(Microtask):如 
 
- 在执行同步任务时,如果遇到异步任务(例如 
-  执行微任务队列: - 当主线程的同步任务执行完毕后,微任务队列会被立即执行,直到微任务队列为空。微任务的优先级高于宏任务,所以它们会在每个事件循环中尽可能多地执行。
- 如果微任务中又生成了新的微任务,这些新的微任务会在当前事件循环中继续执行,直到微任务队列清空。
 
-  执行宏任务队列(延时队列和交互队列): - 当微任务队列为空时,主线程会从宏任务队列中取出任务执行。宏任务队列中的任务是按照加入的顺序依次执行的。 - 延时队列:由 setTimeout、setInterval等产生的任务。
- 交互队列:用户交互事件(如 click、scroll等)会被放入交互队列。
 
- 延时队列:由 
- 在执行宏任务时,如果遇到新的微任务,它们会被添加到微任务队列中,待下一轮微任务执行时处理。
 
- 当微任务队列为空时,主线程会从宏任务队列中取出任务执行。宏任务队列中的任务是按照加入的顺序依次执行的。 
-  重复事件循环: - 事件循环会不断重复,先执行主线程中的同步任务,然后处理微任务队列,接着处理宏任务队列。每次事件循环都会清空微任务队列后才会执行宏任务。
 
事件循环的顺序总结
- 执行主线程中的同步任务。
- 执行微任务队列中的任务(微任务优先级高于宏任务)。
- 执行宏任务队列中的任务(按照加入顺序)。 - 在宏任务执行过程中,如果遇到新的微任务,它们会被添加到微任务队列中,等微任务队列为空时再执行。
 
- 继续下一轮事件循环,重复上述过程。
练习:
console.log(1)setTimeout(() => {console.log(2)
}, 0)const promise = new Promise((resolve, reject) => {console.log(3)setTimeout(() => {new Promise((resolve, reject) => {resolve('success')console.log(8)}).then(data => {console.log(10)})console.log(4)}, 0)resolve('success')
})setTimeout(() => {console.log(5)
}, 0)console.log(6)promise.then(data => {console.log(7)
})console.log(9)答案:
1
3
6
9
7
2
8
4
10
5