js实现promisify
Promisify 的概念
Promisify 是将基于回调的函数转换为返回 Promise 的函数。这种转换在 Node.js 中非常常见,尤其是在处理异步操作时,可以更方便地使用 async/await 或 then/catch 语法。
实现 Promisify 的基本方法
以下是一个简单的 promisify 函数实现,适用于标准的 Node.js 回调风格(即回调函数为 (err, result) 形式):

function promisify(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
};
}
使用示例
假设有一个基于回调的函数 readFile:
const fs = require('fs');
// 原始回调函数
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// 使用 promisify 转换
const readFileAsync = promisify(fs.readFile);
readFileAsync('file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
处理多参数回调
如果回调函数返回多个参数(非标准 (err, result) 形式),可以通过修改 promisify 实现:

function promisify(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
fn(...args, (...results) => {
const error = results.find(result => result instanceof Error);
if (error) {
reject(error);
} else {
resolve(results.length > 1 ? results : results[0]);
}
});
});
};
}
Node.js 内置的 util.promisify
Node.js 的 util 模块提供了内置的 promisify 方法,可以直接使用:
const util = require('util');
const fs = require('fs');
const readFileAsync = util.promisify(fs.readFile);
readFileAsync('file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
自定义 Promisify 的高级实现
如果需要支持更复杂的场景(如绑定 this 或处理特殊回调逻辑),可以扩展实现:
function promisify(fn, context) {
return function (...args) {
return new Promise((resolve, reject) => {
fn.call(context || this, ...args, (err, ...results) => {
if (err) {
reject(err);
} else {
resolve(results.length > 1 ? results : results[0]);
}
});
});
};
}
注意事项
- 确保回调函数的最后一个参数是回调函数本身。
- 如果原始函数需要绑定
this,可以通过context参数传递。 - 对于非标准回调风格(如多个成功参数),需要调整实现逻辑。






