zoukankan      html  css  js  c++  java
  • Node.js 8 中的 util.promisify的详解

    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);
      }, 2000);
     });
    }
     
    async function f1() {
     var x = await resolveAfter2Seconds(10);
     console.log(x); // 10
    }
    f1();

     原文

  • 相关阅读:
    android操作数据库
    Android读写SD卡上的文件
    第四章 函数与程序结构
    getchar()与EOF
    NULL, '',0 '0'的区别
    TCPL 行计数
    行计数
    getchar()用法
    在C语言中,double、long、unsigned、int、char类型数据所占字节数
    队列——解密QQ号
  • 原文地址:https://www.cnblogs.com/Joans/p/10097548.html
Copyright © 2011-2022 走看看