Promisify 是将形如 fn(...args, callback) 且 callback 为 (err, result) => {} 的 Node.js 风格异步函数,封装为返回 Promise 的函数的模式;成功时 resolve,失败时 reject,支持 async/await 和链式调用,提升可读性与错误处理能力。

异步回调函数通过 Promise 化(Promisify)重构,核心是把“传入回调函数”的老式 API,包装成返回 Promise 的新函数,从而支持 async/await 或链式 .then() 调用,提升可读性和错误处理能力。
什么是 Promisify?
Promisify 不是 JavaScript 原生关键字,而是一种模式:将形如 fn(arg1, arg2, callback)(callback 形参在最后,且格式为 (err, result) => {})的 Node.js 风格异步函数,封装为返回 Promise 的函数。成功时 resolve,失败时 reject。
例如 Node.js 的 fs.readFile:
fs.readFile('file.txt', 'utf8', (err, data) => {<br> if (err) throw err;<br> console.log(data);<br>});
立即学习“Java免费学习笔记(深入)”;
手动 Promisify:用 Promise 构造器封装
适用于任何遵循 (...args, callback) 且 callback 为 (err, result) 的函数。
- 创建新函数,接收原函数所需参数(不包括 callback)
- 内部 new Promise,在 callback 中根据 err 决定 resolve 或 reject
- 注意:必须把 callback 放在参数末尾,且只传一次
示例(手动 promisify fs.readFile):
const fs = require('fs');
const readFile = (path, options) => {<br> return new Promise((resolve, reject) => {<br> fs.readFile(path, options, (err, data) => {<br> if (err) reject(err);<br> else resolve(data);<br> });<br> });<br>};之后即可:
readFile('a.txt', 'utf8')<br> .then(data => console.log(data))<br> .catch(err => console.error(err));
使用 util.promisify(Node.js 8.0+ 内置)
Node.js 提供了标准工具函数 util.promisify,一行搞定,且自动继承原函数的属性(如 length)和 this 绑定。
- 要求原函数最后一个参数是 callback,且 callback 第一个参数是 error
- 支持直接 promisify 整个模块(如
util.promisify(fs)),但需谨慎——仅对符合约定的方法生效 - 可配合
bind处理需要指定 this 的场景(如数据库连接实例方法)
示例:
const { promisify } = require('util');<br>const fs = require('fs');const readFile = promisify(fs.readFile);<br>const writeFile = promisify(fs.writeFile);
(async () => {<br> try {<br> const data = await readFile('input.txt', 'utf8');<br> await writeFile('output.txt', data.toUpperCase());<br> console.log('done');<br> } catch (err) {<br> console.error(err);<br> }<br>})();
处理不规范回调函数(非 Node.js 风格)
若第三方库回调是 (result) =>{} 或 (success, data) 等形式,不能直接用 util.promisify,需手动包装:
- 明确回调触发时机(成功/失败分别对应什么参数)
- 自行判断并调用
resolve或reject - 注意避免多次 resolve/reject(Promise 一旦 settled 就不可变)
例如封装 jQuery 的 $.ajax(旧版):
const ajaxPromise = (options) => {<br> return new Promise((resolve, reject) => {<br> $.ajax({<br> ...options,<br> success: resolve,<br> error: (xhr, status, err) => reject(new Error(err || status))<br> });<br> });<br>};
现代项目推荐直接用 fetch(原生返回 Promise),无需 Promisify。


















