1. ホーム
  2. javascript

[解決済み] ES8 async/awaitをストリームで使用するには?

2022-12-07 20:20:23

質問

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を使用して、ストリームを使用する効率を維持したまま、これを変換することは可能でしょうか?

どのように解決するのですか?

async / await はプロミスでのみ動作し、ストリームでは動作しません。独自の構文を持つストリームのようなデータ型を作るアイデアもありますが、それは非常に実験的なもので、詳細には触れません。

とにかく、あなたのコールバックはストリームの終わりを待っているだけなので、プロミスに完璧に適合しています。ストリームをラップすればいいだけです。

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`
});

これで、そのプロミスを待つことができます。

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