Promise 化回调式函数

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'
});
复制代码

参考链接




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值