1. JavaScript 的执行环境
- 单线程:JavaScript 是单线程的,这意味着它在同一时间只能执行一个任务。这种设计使得 JavaScript 在处理并发操作时需要依赖事件循环。
2. 执行栈(Call Stack)
- 定义:执行栈是一个后进先出(LIFO)的数据结构,用于管理函数调用。每当一个函数被调用时,它会被推入栈中;当函数执行完毕后,它会被弹出栈外。
3. Web APIs
- 定义:Web APIs 是浏览器提供的异步操作接口,用于处理如网络请求、定时器、DOM 事件等操作。
- 工作原理:当 JavaScript 代码执行时,如果遇到异步操作,这些操作会被发送到 Web APIs 进行处理。处理完成后,Web APIs 会将相应的回调函数放入消息队列。
4. 消息队列(Callback Queue)
- 定义:消息队列是一个先入先出(FIFO)的数据结构,用于存储待处理的回调函数。只有当执行栈为空时,事件循环才会从消息队列中取出一个回调函数并执行。
5. 微任务队列(Microtask Queue)
- 定义:微任务队列用于存储微任务(如 Promise 的
then
、catch
、finally
回调和MutationObserver
)。 - 优先级:微任务的执行优先级高于宏任务。在处理消息队列中的宏任务之前,事件循环会先执行所有的微任务。
6. 事件循环(Event Loop)
事件循环的主要工作流程如下:
- 检查执行栈:事件循环首先检查执行栈是否为空。
- 处理微任务:
- 如果执行栈为空,事件循环会先处理微任务队列中的所有微任务。
- 处理宏任务:
- 处理完所有微任务后,事件循环会从消息队列中取出一个宏任务并将其推入执行栈中。
- 重复过程:重复步骤 1 至 3,直到消息队列和微任务队列都为空。
7. 任务的优先级
- 微任务:如 Promise 的回调,具有高优先级,优先于宏任务执行。
- 宏任务:如
setTimeout
、setInterval
、I/O 操作等。
事件循环的工作示例
javascript
console.log('A'); // 1
setTimeout(() => {
console.log('B'); // 5
}, 0);
Promise.resolve().then(() => {
console.log('C'); // 3
setTimeout(() => {
console.log('D'); // 7
}, 0);
});
setTimeout(() => {
console.log('E'); // 6
}, 0);
Promise.resolve().then(() => {
console.log('F'); // 4
});
console.log('G'); // 2
标签:console,log,队列,js,任务,循环,机制,执行
From: https://www.cnblogs.com/johnny-cli/p/18512432