ES8 async/await をストリームで使用するにはどうすればいいですか? 質問する

ES8 async/await をストリームで使用するにはどうすればいいですか? 質問する

https://stackoverflow.com/a/18658613/779159組み込みの暗号ライブラリとストリームを使用してファイルの md5 を計算する方法の例です。

var fs = require('fs');
var crypto = require('crypto');

// the file you want to get the hash    
var fd = fs.createReadStream('/some/file/name.txt');
var hash = crypto.createHash('sha1');
hash.setEncoding('hex');

fd.on('end', function() {
    hash.end();
    console.log(hash.read()); // the desired sha1sum
});

// read all file and pipe it (write it) to the hash object
fd.pipe(hash);

しかし、ストリームを使用する効率性を維持しながら、上記のようにコールバックを使用する代わりに ES8 async/await を使用するようにこれを変換することは可能ですか?

ベストアンサー1

キーワードawaitはプロミスに対してのみ機能し、ストリームに対しては機能しません。独自の構文を持つストリームのような追加のデータ型を作成するというアイデアもあります が、それらは非常に実験的なものであり、詳細には触れません

とにかく、コールバックはストリームの終了を待つだけなので、Promise に最適です。ストリームをラップするだけです。

var fd = fs.createReadStream('/some/file/name.txt');
var hash = crypto.createHash('sha1');
hash.setEncoding('hex');
// read all file and pipe it (write it) to the hash object
fd.pipe(hash);

var end = new Promise(function(resolve, reject) {
    hash.on('end', () => resolve(hash.read()));
    fd.on('error', reject); // or something like that. might need to close `hash`
});

より最近のバージョンのNode.jsには、まさにそれを実行するヘルパー関数も存在します。pipelinestream/promisesモジュールから:

import { pipeline } from 'node:stream/promises';
const fd = fs.createReadStream('/some/file/name.txt');
const hash = crypto.createHash('sha1');
hash.setEncoding('hex');

// read all file and pipe it (write it) to the hash object
const end = pipeline(fd, hash);

今、あなたはその約束を待つことができます:

(async function() {
    let sha1sum = await end;
    console.log(sha1sum);
}());

おすすめ記事