异步核心概念
优点
避免阻塞: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();