前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[译] Node.js 8: util.promisify()

[译] Node.js 8: util.promisify()

作者头像
frontoldman
发布2019-09-02 16:55:53
1K0
发布2019-09-02 16:55:53
举报
文章被收录于专栏:樯橹代码樯橹代码

Nodejs 8 有一个新的工具函数 util.promisify()。他将一个接收回调函数参数的函数转换成一个返回Promise的函数。

1、util.promisify()小例子

如果你给以下命令传入文件路径,则会输出文件内容

代码语言:javascript
复制
// 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的一个函数

下面的代码片段显示这个脚本如何使用的

代码语言:javascript
复制
$ 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函数实现

代码语言:javascript
复制
// 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}这样一个对象

代码语言:javascript
复制
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版本附加到一个基于回调的函数。 在以下示例中,fooAsyncfoopromisified版本

代码语言:javascript
复制
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版本

代码语言:javascript
复制
> setImmediate[util.promisify.custom]
[Function]
> setTimeout[util.promisify.custom]
[Function]

5、低版本node兼容库

Jordan Harband写了一个库a polyfill for util.promisify(),用来兼容promisify,使用方法如下

需要注意:

  1. js必须支持es5以上语法
  2. 必须支持Promise
  3. 待完善中

安装

代码语言:javascript
复制
npm install util.promisify

使用方式有两种

第一种,检查是否有内置实现(Node 8)或者使用 polyfill (旧的Node版本)

代码语言:javascript
复制
const promisify = require('util.promisify');

const fs = require('fs');
const readFileAsync = promisify(fs.readFile);

第二种,在旧版本的Node上使用补丁模块

代码语言:javascript
复制
const util = require('util');
require('util.promisify').shim();

const fs = require('fs');
const readFileAsync = util.promisify(fs.readFile);

翻译自 Node.js 8: util.promisify()

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、util.promisify()小例子
  • 2、使用async函数
  • 3、转换有多个参数的回调函数为Promise
  • 4、定制的Promise函数
    • 4.1 定制了promisified版本的标准函数
    • 5、低版本node兼容库
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档