【RTC实时互联网大会 限时免费 马上报名】www.bagevent.com
Node.js 8 提供了新的工具函数:util.promisify
,用于把形如 (err, value) => ...
的回调式函数转换为 Promise 版本。
基本使用
const util = require('util');
const fs = require('fs');
const stat = util.promisify(fs.stat);
stat('.').then((stats) => {
// Do something with `stats`
}).catch((error) => {
// Handle the error.
});
复制代码
当然,也可以使用 Node 8 另一个新功能 async function
调用:
const util = require('util');
const fs = require('fs');
const stat = util.promisify(fs.stat);
async function callStat() {
const stats = await stat('.');
console.log(`This directory is owned by ${stats.uid}`);
}
复制代码
自定义函数的 Promise 版本
通过设置 util.promisify.custom
symbol,可以自定义 util.promisify()
的返回值:
const util = require('util');
function doSomething(foo, callback) {
// ...
}
doSomething[util.promisify.custom] = (foo) => {
return getPromiseSomehow();
};
const promisified = util.promisify(doSomething);
console.log(promisified === doSomething[util.promisify.custom]);
// prints 'true'
复制代码
自定义 Promise symbol 一般用于源函数不遵循 (err, value) => ...
回调的场景,比如 (foo, onSuccessCallback, onErrorCallback)
式回调的函数:
doSomething[util.promisify.custom] = (foo) => {
return new Promise((resolve, reject) => {
doSomething(foo, resolve, reject);
});
};
复制代码
回调函数中包含超过两个参数的函数
诸如以下函数,回调中除了 err
参数,还包含多个参数:
- child_process.exec
- child_process.execFile
- dns.lookup
- dns.lookupService
- fs.read
- fs.write
经过 util.promisify
处理的 Promise 版本会将多个参数组装成对象返回。
例如,dns.lookup()
的回调有三个参数:
- err: Error
- address: 字符串
- family: 整数
Promise 化后,返回 {address: '', family: 3}
这样的对象:
const util = require('util');
const dns = require('dns');
const lookupAsync = util.promisify(dns.lookup);
lookupAsync('nodejs.org')
.then(obj => console.log(obj));
// { address: '104.20.23.46', family: 4 }
复制代码
老版本 Node
Polyfill: util.promisify 模块
npm install util.promisify
复制代码
const util = require('util');
require('util.promisify').shim();
const fs = require('fs');
const readFileAsync = util.promisify(fs.readFile);
复制代码
pify
pify 是一个小而美的 Promise 化工具,处理了一些有用的细节,如自动 this
绑定,这是内置的 util.promisify
中没有的。
const fs = require('fs');
const pify = require('pify');
// Promisify a single function
pify(fs.readFile)('package.json', 'utf8').then(data => {
console.log(JSON.parse(data).name);
//=> 'pify'
});
// Promisify all methods in a module
pify(fs).readFile('package.json', 'utf8').then(data => {
console.log(JSON.parse(data).name);
//=> 'pify'
});
复制代码
参考链接
- Node.js 8: util.promisify()
- util.promisify(original) Node.js 官方文档