用async函数改造回调API的核心是用Promise封装回调并await消费:先手写Promise包装错误优先的回调函数,或用util.promisify自动转换;对不规范API需手动处理resolve/reject;改造后可用try/catch统一捕获异步错误。

用 async 函数改造传统回调 API,核心是用 Promise 封装回调函数,再用 await 消费它——不改原逻辑,只换调用方式。
把回调函数包装成 Promise
传统 Node.js 风格的回调 API(如 fs.readFile、setTimeout)通常形如 fn(...args, callback),其中 callback(err, result) 是标准错误优先模式。要让它支持 await,需将其转为返回 Promise 的函数:
- 创建新函数,内部手动构造
new Promise - 在成功回调中调用
resolve(value),失败时调用reject(err) - 确保错误不被吞掉,尤其注意
try/catch无法捕获异步回调里的异常,必须靠reject
例如封装 setTimeout:
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));<br>await delay(1000); // 等待 1 秒
立即学习“Java免费学习笔记(深入)”;
用 util.promisify 快速转换(Node.js 8+)
Node.js 内置的 util.promisify 可自动将符合错误优先约定的回调函数转为 Promise 版本,省去手写封装:
- 要求原函数最后一个参数是回调,且回调第一个参数是
err - 支持直接传入函数(如
promisify(fs.readFile)),也支持绑定this(如promisify(obj.method).bind(obj)) - 对常见模块(
fs,crypto,dns)已提供promises子模块(如fs.promises.readFile),推荐优先使用
示例:
const { promisify } = require('util');<br>const readFile = promisify(fs.readFile);<br>const data = await readFile('./config.json', 'utf8');
处理不规范的回调 API
有些老库的回调不遵循 (err, result) 格式(比如只有 callback(result),或用事件触发),这时不能直接用 promisify,得手写 Promise 包装:
- 明确回调的触发时机和参数含义,决定何时
resolve、何时reject - 注意清理副作用:比如绑定事件后记得在 resolve/reject 时
removeEventListener,或取消定时器 - 避免多次调用
resolve或reject(Promise 一旦 settled 就不可变,但多余调用可能暴露逻辑漏洞)
例如封装一个只带 success 回调的第三方 SDK:
function loadScript(src) {<br> return new Promise((resolve, reject) => {<br> const script = document.createElement('script');<br> script.src = src;<br> script.onload = () => resolve();<br> script.onerror = () => reject(new Error(`Failed to load ${src}`));<br> document.head.append(script);<br> });<br>}<br>await loadScript('/lib/chart.js');
在 async 函数中统一错误处理
改造完成后,所有异步操作都能用 try/catch 统一捕获错误,不再需要层层嵌套回调里的 if (err) {...}:
-
catch块能捕获 Promise rejected 的错误,包括被reject()抛出的、未捕获的异常、以及throw语句 - 注意:
await后的表达式若本身不是 Promise,会自动包装为Promise.resolve(...),所以不会意外中断流程 - 多个异步操作可按需串行(
await a(); await b();)或并行(await Promise.all([a(), b()]))
例如顺序读取两个文件:
async function readBoth() {<br> try {<br> const a = await readFile('a.txt');<br> const b = await readFile('b.txt');<br> return a + b;<br> } catch (err) {<br> console.error('读取失败:', err.message);<br> throw err;<br> }<br>}


















