核心定义
事件循环 (Event Loop) 是 JavaScript 运行时环境中的一种机制,用于处理异步任务。 由于 JavaScript 是单线程的,因此需要使用事件循环来处理异步任务,避免阻塞主线程。
关键要点
- 单线程: JavaScript 是单线程的,一次只能执行一个任务。
- 异步: JavaScript 可以执行异步任务,例如 AJAX 请求、定时器等。
- 任务队列: 异步任务的回调函数会被放入任务队列中。
- 事件循环: 事件循环会不断地从任务队列中取出任务,放入主线程执行。
运行机制
- 执行栈 (Call Stack): JavaScript 代码首先会被放入执行栈中执行。
- 同步任务: 同步任务会立即执行,并从执行栈中移除。
- 异步任务: 异步任务的回调函数会被放入任务队列中。
- 任务队列 (Task Queue): 任务队列分为宏任务队列 (MacroTask Queue) 和微任务队列 (MicroTask Queue)。
- 宏任务 (MacroTask): 宏任务包括:
-
setTimeout
-setInterval
-setImmediate
(Node.js) -requestAnimationFrame
- I/O - UI 渲染 - 微任务 (MicroTask): 微任务包括:
-
Promise.then
-MutationObserver
-process.nextTick
(Node.js) - 事件循环 (Event Loop): 1. 从宏任务队列中取出一个宏任务执行。 2. 执行完一个宏任务后,会检查微任务队列,并将微任务队列中的所有微任务全部执行完毕。 3. 重复以上步骤。
示例代码
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
// 输出结果:
// script start
// script end
// promise1
// promise2
// setTimeout
解释:
- 首先输出
script start
。 - 然后将
setTimeout
的回调函数放入宏任务队列中。 - 然后执行
Promise.resolve().then()
,将promise1
的回调函数放入微任务队列中。 - 然后输出
script end
。 - 然后检查微任务队列,执行
promise1
的回调函数,输出promise1
。 - 然后执行
promise2
的回调函数,输出promise2
。 - 然后检查宏任务队列,执行
setTimeout
的回调函数,输出setTimeout
。
内部联系
- JavaScript: 事件循环是 JavaScript 运行时环境中的一种机制。
- 异步: 事件循环用于处理异步任务。
- Promise: Promise 是一种用于处理异步操作的对象。