做慕课视频的时候,仔细琢磨了一下,发现之前讲的还是有问题,所以重新录了一遍。
标签: 回调
-

Node.js 8 中的 util.promisify
Node.js 8 于上个月月底正式发布,带来了很多新特性。其中比较值得注意的,便有
util.promisify()这个方法。如果你已经很熟悉 Promise,请继续往下看。如果你还不熟悉 Promise,可以先跳过去看下下章:Promise 介绍。
util.promisify()虽然 Promise 已经普及,但是 Node.js 里仍然有大量依赖回调的异步函数,如果我们把每个函数都封装一遍,那真是齁麻烦齁麻烦的,比齁还麻烦。
所以 Node.js 8 就提供了
util.promisify()这个方法,方便我们把原来的异步回调方法改成支持 Promise 的方法,接下来,想继续.then().then().then()搞队列,还是 await 就看实际需要了。我们看下范例,让读取目录文件状态的
fs.stat支持 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.js 的回调风格,所有函数都可以这样转换。也就是说,只要满足下面两个条件,无论是不是原生方法,都可以:
- 最后一个参数是回调函数
- 回调函数的参数为
(err, result),前面是可能的错误,后面是正常的结果
结合 Await/Async 使用
同样是上面的例子,如果想要结合 Await/Async,可以这样使用:
const util = require('util'); const fs = require('fs'); const stat = util.promisify(fs.stat); async function readStats(dir) { try { let stats = await stat(dir); // Do something with `stats` } catch (err) { // Handle the error. console.log(err); } } readStats('.');自定义 Promise 化处理函数
那如果现有的使用回调的函数不符合这个风格,还能用
util.promisify()么?答案也是肯定的。我们只要给函数增加一个属性util.promisify.custom,指定一个函数作为 Promise 化处理函数,即可。请看下面的代码:const util = require('util'); // 这就是要处理的使用回调的函数 function doSomething(foo, callback) { // ... } // 给它增加一个方法,用来在 Promise 化时调用 doSomething[util.promisify.custom] = function(foo) { // 自定义生成 Promise 的逻辑 return getPromiseSomehow(); }; const promisified = util.promisify(doSomething); console.log(promisified === doSomething[util.promisify.custom]); // prints 'true'如此一来,任何时候我们对目标函数 doSomething 进行 Promise 化处理,都会得到之前定义的函数。运行它,就会按照我们设计的特定逻辑返回 Promise 实例。
我们就可以升级以前所有的异步回调函数了。
