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


Nodejs 8には新しいツール関数util.promisifyがあります.彼は受信したコールバック関数パラメータの関数をPromiseに戻る関数に変換しました.
1、util.promisify()の小さい例
以下のコマンドにファイルのパスを入力すると、ファイルの内容が出力されます.
// 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);
  });
第1行では、プログラムはpromisify()を使用して、コールバック関数に基づく方法fs.readFile()を変換し、promiseに戻る関数として使用する.
下のコードセグメントはこのスクリプトがどのように使用されるかを示します.
$ 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関数で実現します.
// 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.lookuplace
  • fs.read
  • fs.write
  • これらの関数をプロミスに変換すると、一つの値ではなく複数のパラメータからなるオブジェクトが返されます.例えば、dns.lookupのコールバック関数は、以下のいくつかのパラメータを含む.
  • err:Errer
  • address:string
  • family:integer
  • Promiseに変換すると、そのパラメータは{address, family}というオブジェクトになります.
    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バージョンである.
    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バージョンがあります.
    > setImmediate[util.promisify.custom]
    [Function]
    > setTimeout[util.promisify.custom]
    [Function]
    5、低バージョンのnode互換ライブラリ
    Jordan Harbandは、プロmisifyと互換するためのライブラリa polyfill for util.promisify()を書いています.使い方は以下の通りです.
    注意が必要です
  • jsはes 5以上の文法
  • をサポートしなければなりません.
  • Promise
  • をサポートしなければならない.
  • 改善待ち中
  • インストール
    npm install util.promisify
    使い方は二つあります.
    第一に、内蔵実現(Node 8)があるかどうか、またはpolyfill(旧Nodeバージョン)を使用するかどうかを確認する.
    const promisify = require('util.promisify');
    
    const fs = require('fs');
    const readFileAsync = promisify(fs.readFile);
    第二に、旧バージョンのNodeにパッチモジュールを使用します.
    const util = require('util');
    require('util.promisify').shim();
    
    const fs = require('fs');
    const readFileAsync = util.promisify(fs.readFile);
    翻訳はNode.js 8:util.promisify()から