基本使用
将 callback 转为 promise 对象,首先要确保这个 callback 为一个错误优先的回调函数,即
(err, value) => ...err 指定一个错误参数,value 为返回值。
const { promisify } = require('util');const readFilePromisify = util.promisify(fs.readFile); // 转化为 promisereadFilePromisify('text.txt', 'utf8').then(result => console.log(result)) // Nodejs Callback 转 Promise 对象测试.catch(err => console.log(err));
util.promisify.custom 基本使用
const util = require('util');function doSomething(foo, callback) {// ...}// 利用 util.promisify.custom 这个 key 自定义 promisify 行为doSomething[util.promisify.custom] = (foo) => {return getPromiseSomehow();};// 调用 util.promisify 方法const promisified = util.promisify(doSomething);// 返回的 promisified 就是刚才自定义的 doSomething[util.promisify.custom] 函数console.log(promisified === doSomething[util.promisify.custom]);// prints 'true'const fs = require('fs');fs.readFile[util.promisify.custom] = () => {return Promise.reject('该文件暂时禁止读取');}const readFilePromisify = util.promisify(fs.readFile);readFilePromisify('text.txt', 'utf8').then(result => console.log(result)).catch(err => console.log(err)); // 该文件暂时禁止读取
实现
const kCustomPromisifiedSymbol = Symbol('util.promisify.custom');promisify.custom = kCustomPromisifiedSymbol;function promisify(original) {// 保证 promisify 处理仅对函数生效if (typeof original !== 'function') {throw new Error('the original argument must be of type Function.Received type undefined');}if (original[kCustomPromisifiedSymbol]) {const fn = original[kCustomPromisifiedSymbol];if (typeof fn !== 'function') {throw new Error('The "mayJunPromisify.custom" property must be of type Function. Received type number');}return Object.defineProperty(fn, kCustomPromisifiedSymbol, {value: fn,enumerable: false,writable: false,configurable: true})}// 将传入的 original 函数 promisify 的关键处理逻辑,// 此时的 fn 即为 promisify 化后的 original 结果函数function fn(...args) {return new Promise((resolve, reject) => {try {original.call(this, ...args, (err, result) => {if (err) {reject(err);} else {resolve(result);}})} catch(err) {reject(err);}})}return fn;}
