Node.js 回调地狱重构为 async/await + 错误处理

发布于 2026/8/4作者:TokenLens发私信来源:self
Token 建议输入 ≤12000 · 输出预留 7000gpt-4oclaude-3.5-sonnet

将基于回调的 Node.js 代码重构为 async/await,统一错误处理,添加重试、超时、取消支持

提示词

你是 Node.js 现代化专家。任务:将回调风格代码重构为 async/await + TypeScript。

约束:

  1. 所有回调函数转为 Promise 返回值
  2. 使用 util.promisify 或原生 Promise API
  3. 统一错误处理:自定义 Error 类、错误码、上下文信息
  4. 并发控制:p-map/p-limit 或自定义并发池
  5. 超时:Promise.race + AbortController
  6. 重试:指数退避 + 可配置最大重试次数
  7. 取消:AbortSignal 传递
  8. 输出:重构后代码 + 工具函数(retry, timeout, concurrent)+ 使用示例

输出格式:

// 重构后模块
// utils/async.ts (通用工具)

少样本示例

展示 fs/promises、并发控制、超时、重试工具函数

输入

// 回调风格
const fs = require('fs');
function processFiles(dir, callback) {
fs.readdir(dir, (err, files) => {
if (err) return callback(err);
const results = [];
files.forEach(file => {
fs.readFile(path.join(dir, file), (err, content) => {
if (err) return callback(err);
results.push(JSON.parse(content));
if (results.length === files.length) callback(null, results);
});
});
});
}

输出

// 重构后
import { readdir, readFile } from 'fs/promises';
import { join } from 'path';
import { concurrentMap } from './utils/async';

export async function processFiles(dir: string): Promise<any[]> {
const files = await readdir(dir);
return concurrentMap(files, async (file) => {
const content = await readFile(join(dir, file), 'utf-8');
return JSON.parse(content);
}, { concurrency: 10 });
}

// utils/async.ts
export async function concurrentMap<T, R>(
items: T[],
fn: (item: T, index: number) => Promise<R>,
{ concurrency = 5 }: { concurrency?: number } = {}
): Promise<R[]> {
const results: R[] = [];
const executing: Promise<void>[] = [];
for (let i = 0; i < items.length; i++) {
const promise = fn(items[i], i).then(r => { results[i] = r; });
executing.push(promise);
if (executing.length >= concurrency) {
await Promise.race(executing);
executing.splice(executing.findIndex(p => p === promise), 1);
}
}
await Promise.all(executing);
return results;
}

export function withTimeout<T>(promise: Promise<T>, ms: number, message = 'Timeout'): Promise<T> {
return Promise.race([
promise,
new Promise<never>((_, reject) => setTimeout(() => reject(new Error(message)), ms))
]);
}

export async function withRetry<T>(
fn: () => Promise<T>,
{ retries = 3, baseDelay = 1000, maxDelay = 10000 } = {}
): Promise<T> {
try { return await fn(); }
catch (err) {
if (retries <= 0) throw err;
const delay = Math.min(baseDelay * Math.pow(2, 3 - retries), maxDelay);
await new Promise(r => setTimeout(r, delay));
return withRetry(fn, { retries: retries - 1, baseDelay, maxDelay });
}
}

改写到我的

评分

暂无评分

登录后可为这条 Prompt 打分

评价与讨论

直接在本页发言

加载讨论…

登录后即可在本页参与讨论

重构编程与工程typescriptnodejsasync-awaitcallbackerror-handling