Nodejs 8 有一个新的东西函数 util.promisify()。他将一个吸收回调函数参数的函数转换成一个返回Promise的函数。
1、util.promisify()小例子
假如你给以下敕令传入文件途径,则会输出文件内容
// echo.js
const {promisify} = require('util');
const fs = require('fs');
const readFileAsync = promisify(fs.readFile); // (A)
const filePath = process.argv[2];
readFileAsync(filePath, {encoding: 'utf8'})
.then((text) => {
console.log('CONTENT:', text);
})
.catch((err) => {
console.log('ERROR:', err);
});
注重:在第一行,顺序运用promisify()
转换基于回调函数的要领fs.readFile()
成一个返回promise
的一个函数
下面的代码片断显现这个剧本怎样运用的
$ node echo.js echo.js
CONTENT: const {promisify} = require('util');
···
$ node echo.js unknown.txt
ERROR: { Error: ENOENT: no such file or directory, ··· }
2、运用async
函数
一样的功用,然则经由过程async函数完成
// echoa.js
const {promisify} = require('util');
const fs = require('fs');
const readFileAsync = promisify(fs.readFile);
const filePath = process.argv[2];
async function main() {
try {
const text = await readFileAsync(filePath, {encoding: 'utf8'});
console.log('CONTENT:', text);
}
catch (err) {
console.log('ERROR:', err);
}
}
main();
3、转换有多个参数的回调函数为Promise
下面的函数的回调函数吸收多于一个的参数(除了error参数)
child_process.exec
child_process.execFile
dns.lookup
dns.lookupService
fs.read
fs.write
假如你转换这些函数为promise,它会返回一个对象(由多个参数构成的对象,而不是一个值)。比方,dns.lookup
的回调函数包括下面几个参数
err : Error
address : string
family : integer
转换成Promise以后,它的参数将会变成{address, family}
如许一个对象
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 }
promisify()
经由过程内部标记internal/util/customPromisifyArgs
处置惩罚非规范回调函数。因而不引荐传入一个非规范的回调函数,也不该该去转换我们本身完成的回调(ps:本身就直接写Promise就好了。。。)
4、定制的Promise函数
promisified
的API来源于util.promisify.custom
,它许可您将一个promisified
版本附加到一个基于回调的函数。 在以下示例中,fooAsync
是foo
的promisified
版本
const util = require('util');
function foo() {
return 'abc';
}
async function fooAsync() {
return 'abc';
}
foo[util.promisify.custom] = fooAsync;
console.log(util.promisify(foo) === fooAsync); // true
4.1 定制了promisified
版本的规范函数
如今,有两个规范函数有定制的promisified
版本
> setImmediate[util.promisify.custom]
[Function]
> setTimeout[util.promisify.custom]
[Function]
5、低版本node兼容库
Jordan Harband写了一个库a polyfill for util.promisify(),用来兼容promisify,运用要领以下
须要注重:
js必需支撑es5以上语法
必需支撑
Promise
待完美中
装置
npm install util.promisify
运用体式格局有两种
第一种,搜检是不是有内置完成(Node 8)或许运用 polyfill (旧的Node版本)
const promisify = require('util.promisify');
const fs = require('fs');
const readFileAsync = promisify(fs.readFile);
第二种,在旧版本的Node上运用补丁模块
const util = require('util');
require('util.promisify').shim();
const fs = require('fs');
const readFileAsync = util.promisify(fs.readFile);