Nodejs util 模块提供了很多工具函数。为了解决回调地狱问题,Nodejs v8.0.0 提供了 promisify 方法可以将 Callback 转为 Promise 对象。
工作中对于一些老项目,有 callback 的通常也会使用 util.promisify 进行转换,之前更多是知其然不知其所以然,本文会从基本使用和对源码的理解实现一个类似的函数功能。
1. Promisify 简单版本实现
在介绍 util.promisify 的基础使用之后,实现一个自定义的 util.promisify 函数的简单版本。
1.1 util promisify 基本使用
将 callback 转为 promise 对象,首先要确保这个 callback 为一个错误优先的回调函数,即 (err, value) => … err 指定一个错误参数,value 为返回值。
以下将以 fs.readFile 为例进行介绍。
创建一个 text.txt 文件
创建一个 text.txt 文件,写入一些自定义内容,下面的 Demo 中我们会使用 fs.readFile 来读取这个文件进行测试。
// text.txt
Nodejs Callback 转 Promise 对象测试
传统的 Callback 写法
const util = require('util');
fs.readFile('text.txt', 'utf8', function(err, result) {
console.error('Error: ', err);
console.log('Result: ', result); // Nodejs Callback 转 Promise 对象测试
});
Promise 写法
这里我们使用 util.promisify 将 fs.readFile 转为 Promise 对象,之后我们可以进行 .then、.catch 获取相应结果
const { promisify } = require('util');
const readFilePromisify = util.promisify(fs.readFile); // 转化为 promise
readFilePromisify('text.txt', 'utf8')
.then(result => console.log(result)) // Nodejs Callback 转 Promise 对象测试
.catch(err => console.log(err));
1.2 自定义 mayJunPromisify 函数实现
自定义 mayJunPromisify 函数实现 callback 转换为 promise,核心实现如下:
- 行 {1} 校验传入的参数 original 是否为 Function,不是则抛错
- promisify(fs.readFile) 执行之后会返回一个函数 fn,行 {2} 定义待返回的 fn 函数,行 {3} 处返回
- fn 返回的是一个 Promise 对象,在返回的 Promise 对象里执行 callback 函数
function mayJunPromisify(original) {
if (typeof original !== 'function') { // {1} 校验
throw new Error('The "original" argument must be of type Function. Received type undefined')
}
functio