深入理解JavaScript事件循环机制
·
Event Loop 基础原理
JavaScript 的运行时基于单线程事件循环模型,核心分为调用栈(Call Stack)、微任务队列(Microtask Queue)和宏任务队列(Macrotask Queue)。调用栈执行同步代码,遇到异步任务时根据类型分发:
- 宏任务:
setTimeout、setInterval、I/O 操作 - 微任务:
Promise.then、process.nextTick、MutationObserver
执行顺序规则:
- 清空当前调用栈中的同步代码
- 检查微任务队列并执行所有微任务
- 取出一个宏任务执行
- 重复上述过程
console.log('同步1');
setTimeout(() => console.log('宏任务1'), 0);
Promise.resolve().then(() => console.log('微任务1'));
// 输出顺序: 同步1 → 微任务1 → 宏任务1
异步编程演进史
Callback 阶段
fs.readFile('file.txt', (err, data) => {
if (err) throw err;
console.log(data);
});
问题:回调地狱(Callback Hell),难以维护。
Promise 阶段
readFilePromise('file.txt')
.then(data => console.log(data))
.catch(err => console.error(err));
改进:链式调用,错误集中处理。
Generator + Co 阶段
function* gen() {
const data = yield readFilePromise('file.txt');
console.log(data);
}
co(gen);
特性:通过yield暂停执行,需要配合执行器使用。
Async/Await 阶段
async function main() {
try {
const data = await readFilePromise('file.txt');
console.log(data);
} catch (err) {
console.error(err);
}
}
本质:语法糖,将Generator+Promise的流程控制自动化。
Promise 核心实现
基础版Promise
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
}
};
executor(resolve);
}
}
Promise.all 实现
MyPromise.all = function(promises) {
return new Promise((resolve, reject) => {
const results = [];
let completed = 0;
promises.forEach((promise, index) => {
promise.then(value => {
results[index] = value;
if (++completed === promises.length) resolve(results);
}).catch(reject);
});
});
};
Async/Await 高级技巧
错误处理模式
// 方案1: try-catch
async function fetchData() {
try {
return await axios.get('/api');
} catch (err) {
console.error('Request failed', err);
throw err; // 继续向上传递
}
}
// 方案2: 高阶函数包装
function withErrorHandling(fn) {
return async (...args) => {
try {
return await fn(...args);
} catch (err) {
sentry.captureException(err);
return null;
}
};
}
并行执行优化
// 低效写法(顺序执行)
async function slow() {
const a = await fetchA();
const b = await fetchB();
return { a, b };
}
// 高效写法(并行执行)
async function fast() {
const [a, b] = await Promise.all([fetchA(), fetchB()]);
return { a, b };
}
性能优化实战
微任务优先策略
function heavyTask() {
// 将CPU密集型任务分解为微任务
return new Promise(resolve => {
const chunk = () => {
if (workQueue.isEmpty()) {
resolve();
} else {
processChunk(workQueue.dequeue());
Promise.resolve().then(chunk); // 插入微任务队列
}
};
chunk();
});
}
取消异步流程
function createCancelablePromise(promise) {
let isCancelled = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise.then(
value => !isCancelled && resolve(value),
error => !isCancelled && reject(error)
);
});
return {
promise: wrappedPromise,
cancel() { isCancelled = true; }
};
}
可视化辅助理解
常见面试题解析
问题1:以下代码输出顺序
setTimeout(() => console.log(1), 0);
Promise.resolve().then(() => console.log(2));
console.log(3);
// 答案: 3 → 2 → 1
问题2:如何实现Promise.race
MyPromise.race = function(promises) {
return new Promise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve).catch(reject);
});
});
};
问题3:async函数返回什么
async function foo() { return 42; }
const result = foo();
console.log(result instanceof Promise); // true
更多推荐

所有评论(0)