Node.js 8带来了 很多新特性 。其中比较值得注意的,便有 util.promisify() 这个方法。

util.promisify()

虽然 Promise 已经普及,但是 Node.js 里仍然有大量的依赖回调的异步函数,如果我们每个函数都封装一次,还麻烦。

所以 Node8 就提供了 util.promisify() 这个方法,方便我们快捷的把原来的异步回调方法改成返回 Promise 实例的方法,接下来,想继续用队列,还是 await 就看需要了。

例如 读取文件状态的操作:

var fs = require("fs");
 //读取文件的状态;
 fs.stat(path,callback);

fs.stat("./wenjian.txt",function(err,stats){
console.log(err);
console.log(stats);
// 获取文件的大小;
console.log(stats.size);
// 获取文件最后一次访问的时间;
console.log(stats.atime.toLocaleString());
// 文件创建的时间;
console.log(stats.birthtime.toLocaleString());
// 文件最后一次修改时间;
console.log(stats.mtime.toLocaleString());
// 状态发生变化的时间;
console.log(stats.ctime.toLocaleString())
//判断是否是目录;是返回true;不是返回false;
console.log(stats.isFile())
// 判断是否是文件;是返回true、不是返回false;
console.log(stats.isDirectory())
})  

将读取文件状态的回调函数通过util来promise化:

const util = require('util');
const fs = require('fs'); const stat = util.promisify(fs.stat);
stat('./path').then((stats) => {
// Do something with `stats`
}).catch((error) => {
// Handle the error.
});

只要符合 Node.js 的回调风格,所有函数都可以这样转换。也就是说,满足下面两个条件即可。

  1. 最后一个参数是函数
  2. 回调函数的参数为 (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('./path'); //调用

自定义 Promise 化处理函数

那如果函数不符合这个风格,还能用 util.promisify() 么?答案也是肯定的。我们只要给函数增加一个属性,util.promisify.custom ,指定一个函数作为 Promise 化处理函数,即可。请看下面的代码:

const util = require('util');

function doSomething(foo, callback) {
// ...
} doSomething[util.promisify.custom] = function(foo) {
return getPromiseSomehow();
}; const promisified = util.promisify(doSomething);
console.log(promisified === doSomething[util.promisify.custom]);
// prints 'true'

如此一来,任何时候我们对目标函数 doSomething 进行 Promise 化处理,都会得到之前定义的函数。运行它,就会按照我们设计的特定逻辑返回 Promise 实例。

我们就可以升级以前所有的异步回调函数了。

Promise 介绍

因为种种历史原因,JS 当中有大量异步函数。这些异步函数,大多要依赖回调进行处理(这里我觉得把事件侦听算作回调也是合理的),但是回调嵌套层次一多,就会形成所谓的“回调陷阱”,让开发者苦不堪言。

为了解决这个问题,开发社区经过摸索,总结出来一套名为 Promise/A+ 的解决方案。大体上来说,这套方案通过使用 “Promise 回调实例”包裹原先的回调函数,可以将原先复杂的嵌套展开、铺平,从而降低开发和维护的难度和成本。

ES2015(ES6)里包含了 Promise 标准,如今已经在大部分运行时里实装,我们可以放心大胆的使用它。而且,由于 Promise 不需要新的语法元素,所以即使在不支持原生 Promise 的环境里也可以使用类库,比如 Q 或者 Bluebird ,甚至 jQuery 。

在小程序里也有效哟。

ES2017 增加了 Await/Async 语法,但请注意, Await 后面必须跟 Promise 实例才能实现异步。所以,大家还是把 Promise 的概念学好吧!

function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, );
});
} async function f1() {
var x = await resolveAfter2Seconds();
console.log(x); //
}
f1();

原文

Node.js 8 中的 util.promisify的详解的更多相关文章

  1. Node.js:常用工具util

    概要:本篇博客的主要内容是介绍node.js的常用工具util. 1.util.inherits util.inherits(constructor,superConstructor)是一个实现对象间 ...

  2. Node.js中环境变量process.env详解

    Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...

  3. JS中的函数节流throttle详解和优化

    JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...

  4. 前端后台以及游戏中使用Google Protocol Buffer详解

    前端后台以及游戏中使用Google Protocol Buffer详解 0.什么是protoBuf protoBuf是一种灵活高效的独立于语言平台的结构化数据表示方法,与XML相比,protoBuf更 ...

  5. js正则实现二代身份证号码验证详解

    js正则实现二代身份证号码验证详解 根据[中华人民共和国国家标准 GB 11643-1999]中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至 ...

  6. 国际化,java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  7. JS魔法堂:LINK元素深入详解

    一.前言 我们一般使用方式为 <link type="text/css" rel="stylesheet" href="text.css&quo ...

  8. java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  9. java.util.ResourceBundle使用详解(转)

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

随机推荐

  1. x509证书相关内容

    什么是证书 X.509证书,其核心是根据RFC 5280编码或数字签名的数字文档.    实际上,术语X.509证书通常指的是IETF的PKIX证书和X.509 v3证书标准的CRL 文件,即如RFC ...

  2. Requests卡死问题

    https://www.cnblogs.com/niansi/p/7143736.html https://blog.csdn.net/pilipala6868/article/details/807 ...

  3. SSM(Spring4.x.x+SpringMVC4.x.x+Mybatis3.4.x)框架整合

    本文是参考SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)修改而来的 一.环境 1. Myeclipse2016 2. Mysql 二.具体步骤 1. 整合Spring和 ...

  4. 结合API Gateway和Lambda实现登录时的重定向和表单提交请求(Python3实现)

    1. 创建Lambda函数,代码如下: from urllib import parse def lambda_handler(event, context): body = event['body' ...

  5. SynchronousQueueDemo

    1.ArrayDeque, (数组双端队列) 2.PriorityQueue, (优先级队列) 3.ConcurrentLinkedQueue, (基于链表的并发队列) 4.DelayQueue, ( ...

  6. vue 脚手架关于路由的一点理解

    https://router.vuejs.org/zh/ 可以先翻翻文档看看介绍啊,一般我不怎么喜欢看文档,都是直接看人家案例,在回头看文档的,所以学习速度慢很多,希望我以后成为一个爱学习的妹子,比较 ...

  7. centos安装图形界面

    1.首先安装X(X Window System),命令为  yum groupinstall "X Window System"   回车 2.由于这个软件组比较大,安装过程会比较 ...

  8. 单点登录系统和CAS的简介

    ---恢复内容开始--- 什么是单点登录? 单点登录(Single Sign On),简称为SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以 ...

  9. GitHub Toturial

    GitHub Toturial Git Summary 1. 设置姓名和email git config --global user.name "YuboFeng" git con ...

  10. archer docker安装部署

    1.准备配置文件从archer项目官网下载/archer/settings.py文件,根据自己情况放到相应的目录我下载后放到如下目录[root@lenovo opt]# mkdir -p /opt/a ...