🐛 异步Bug无法复现,测试妹子怀疑人生...
// 💀 你以为这样写很酷?其实是在挖坑 (async () => { await initApp(); // 崩了也不知道,静悄悄泄漏 })(); // 堆代码 duidaima.com // 🛡️ 一个void关键字,拯救你的半夜睡眠 void (async () => { try { await initApp(); } catch (error) { console.error('应用初始化失败:', error); } })();void 的作用是:显式丢弃 Promise 返回值,防止因未处理的拒绝状态导
console.time()太业余了 console.time('慢查询'); await slowDatabaseQuery(); console.timeEnd('慢查询');🎯 专业选手都用 Performance API
const measureAsync = async <T>(name: string, fn: () =>Promise<T>) => { const startMark = `${name}-start`; const endMark = `${name}-end`; performance.mark(startMark); try { returnawait fn(); } finally { performance.mark(endMark); performance.measure(name, startMark, endMark); const [entry] = performance.getEntriesByName(name); console.log(`🚀 ${name}: ${entry.duration.toFixed(3)}ms`); // 清理标记,避免内存堆积 performance.clearMarks(startMark); performance.clearMarks(endMark); performance.clearMeasures(name); } }; // 使用示例:精确定位慢接口 await measureAsync('用户数据查询', () => fetchUserData());🔥 优势:
3.适用于数据库、外部接口的慢调用排查
async function loadUserData() { const profile = await fetch('/api/profile'); const orders = await fetch('/api/orders'); const preferences = await fetch('/api/preferences'); }🎯 AbortController:一键叫停所有任务。不是只有 fetch 才能取消,任何异步 Promise 都能中断:
class TaskManager { private controller = new AbortController(); async loadUserData() { const signal = this.controller.signal; try { const [profile, orders, preferences] = awaitPromise.all([ fetch('/api/profile', { signal }), fetch('/api/orders', { signal }), fetch('/api/preferences', { signal }) ]); return { profile, orders, preferences }; } catch (error) { if (error.name === 'AbortError') { console.log('✅ 任务已取消,资源已释放'); returnnull; } throw error; } } // 用户离开页面时调用 cleanup() { this.controller.abort(); } }痛点4:大数据处理,内存爆炸
async function processAllUsers() { const users = await fetch('/api/users?limit=100000'); return users.map(transformUser); // 💀 内存:GG }直接这么请求,多来几个这样的请求,不仅服务器要裂开了,前端内存也要撑爆了。此时async generator派上用场了,用 async generator 流式处理异步数据,像水流一样优雅:
async function* streamUsers(batchSize = 1000) { let offset = 0; while (true) { const response = await fetch(`/api/users?limit=${batchSize}&offset=${offset}`); const users = await response.json(); if (users.length === 0) break; for (const user of users) { yield transformUser(user); } offset += batchSize; } } // 使用:内存占用稳定,体验丝滑 asyncfunction processUsers() { let processedCount = 0; forawait (const user of streamUsers()) { await processUser(user); processedCount++; // 实时反馈进度 if (processedCount % 100 === 0) { updateProgress(processedCount); } } }非常适合处理大批量分页、日志流、视频帧、图像数据,还能节省大量内存。
class BufferManager { static merge(buffers: ArrayBuffer[]): ArrayBuffer { const totalLength = buffers.reduce((sum, buf) => sum + buf.byteLength, 0); const result = newUint8Array(totalLength); let offset = 0; for (const buffer of buffers) { result.set(newUint8Array(buffer), offset); offset += buffer.byteLength; } return result.buffer; } static slice(buffer: ArrayBuffer, start: number, end: number): ArrayBuffer { // 零拷贝切片,性能爆表 return buffer.slice(start, end); } static toHex(buffer: ArrayBuffer): string { returnArray.from(newUint8Array(buffer)) .map(b => b.toString(16).padStart(2, '0')) .join(''); } } // 实际应用:文件上传分片合并 const chunks = await uploadFileInChunks(file); const merged = BufferManager.merge(chunks);千万注意, 别使用字符串拼接处理二进制。
function mergeFiles(files: string[]) { return files.join(''); // 💀 性能:史诗级灾难 }之前看到过这样的代码处理二进制,真的想问一句,你是认真的吗?
async function processPayment(amount: number) { try { await validatePayment(amount); } catch (error) { throw new Error('支付失败'); // 💀 原始错误信息丢失 } }如果你总这样写代码, 会出现错误丢失上下文,调试如盲人摸象。可以用 cause关联异步错误链,快速定位根因
try { await validatePayment(); } catch (err) { throw new OrderError("支付失败", { cause: err }); }Error Cause 保留完整错误链,在 Sentry、日志系统、链路追踪里可以再现全貌:
console.error(e.cause); // 原始错误总结