异步核心概念
优点
避免阻塞:JavaScript是单线程语言,异步操作可防止长时间任务阻塞主线程
提升性能:充分利用I/O等待时间处理其他任务
响应式体验:保持UI流畅响应,特别是在浏览器环境中
事件循环机制
console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve().then(() => console.log('Promise'));
console.log('End');
执行上下文
调用栈(Call Stack):同步代码执行容器
任务队列(Task Queue):存放宏任务(setTimeout、I/O)
微任务队列(Microtask Queue):存放微任务(Promise、MutationObserver)
异步编程演进史
回调函数(Callback)
function fetchData(callback) {
setTimeout(() => {
callback('Data received');
}, 1000);
}
fetchData((data) => {
console.log(data);
});
回调函数存在的问题:回调地狱(Callback Hell)
getUser(userId, (user) => {
getOrders(user.id, (orders) => {
getProducts(orders[0].id, (products) => {
renderPage(user, orders, products);
});
});
});
Promise(ES6)
const promiseExample = new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > 0.5 ? resolve('Success!') : reject(new Error('Failed'));
}, 1000);
});
promiseExample
.then(console.log)
.catch(console.error);
async/await(ES2017)
async function fetchUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch failed:', error);
}
}
Promise 深度解析
状态管理
Pending(进行中)
Fulfilled(已成功)
Rejected(已失败)
链式调用
checkInventory()
.then((stock) => placeOrder(stock))
.then((order) => processPayment(order))
.then((receipt) => sendConfirmation(receipt))
.catch(handleErrors);
组合方法
Promise.all([api1, api2, api3])
.then(([res1, res2, res3]) => { });
Promise.race([fastAPI, slowAPI])
.then(firstResult => { });
Promise.allSettled([req1, req2])
.then(results => { });
async/await最佳实践
错误处理模式
async function safeFetch() {
try {
const res = await fetch(url);
return await res.json();
} catch (err) {
console.error('Request failed:', err);
return null;
}
}
const asyncHandler = (promise) =>
promise.then(data => [null, data])
.catch(err => [err, null]);
并行优化
const user = await getUser();
const orders = await getOrders(user.id);
const [user, orders] = await Promise.all([
getUser(),
getOrders(userId)
]);
循环中的异步
array.forEach(async item => {
await process(item);
});
for (const item of array) {
await process(item);
}
await Promise.all(array.map(item => process(item)));
高级异步模式
发布订阅模式
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
(this.events[event] || (this.events[event] = [])).push(listener);
}
emit(event, ...args) {
(this.events[event] || []).forEach(listener => listener(...args));
}
}
Web Workers
const worker = new Worker('worker.js');
worker.postMessage({
type: 'CALC', data: bigArray
});
worker.onmessage = (e) => {
console.log('Result:', e.data);
};
self.onmessage = function (e) {
if (e.data.type === 'CALC') {
const result = heavyCalculation(e.data.data);
self.postMessage(result);
}
};
错误处理策略
全局错误捕获
window.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled rejection:', event.reason);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});
重试机制
async function retry(fn, retries = 3, delay = 1000) {
try {
return await fn();
} catch (err) {
if (retries <= 0) throw err;
await new Promise(res => setTimeout(res, delay));
return retry(fn, retries - 1, delay * 2);
}
}
性能优化
节流防抖
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
function throttle(fn, interval) {
let lastTime = 0;
return (...args) => {
const now = Date.now();
if (now - lastTime >= interval) {
fn(...args); lastTime = now;
}
};
}
请求缓存
const apiCache = new Map();
async function cachedFetch(url) {
if (apiCache.has(url)) {
return apiCache.get(url);
}
const response = await fetch(url);
const data = await response.json();
apiCache.set(url, data); return data;
}
开发场景
async function loadPageData() {
const [user, posts] = await Promise.all([fetch('/api/user'), fetch('/api/posts')]);
return { user: await user.json(), posts: await posts.json() };
}
文件上传处理
async function uploadFiles(files) {
const uploadPromises = files.map(file => {
const formData = new FormData(); formData.append('file', file);
return fetch('/upload', { method: 'POST', body: formData });
});
const results = await Promise.allSettled(uploadPromises);
}
结语
1.优先使用async/await:提升代码可读性
2.避免过度并行:控制并发数量(使用p-limit等库)
3.及时清理资源:取消不必要的请求(AbortController)
4.监控异步性能:使用Performance API进行分析
5.保持错误可追踪:附加上下文错误信息
const controller = new AbortController();
fetch(url, {
signal: controller.signal
}).then().catch(err => {
if (err.name === 'AbortError') {
console.log('Request aborted');
}
});
controller.abort();