wake-up-neo.com

Wie verwende ich ES8 async/await mit Streams?

In https://stackoverflow.com/a/18658613/779159 ist ein Beispiel für die Berechnung des MD5 einer Datei mithilfe der integrierten Kryptobibliothek und der Streams.

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

Aber ist es möglich, dies in die Verwendung von ES8 async/await umzuwandeln, anstatt den Rückruf wie oben beschrieben zu verwenden, während die Effizienz der Verwendung von Streams beibehalten wird?

29
user779159

async/await funktioniert nur mit Versprechen, nicht mit Streams. Es gibt Vorschläge, einen zusätzlichen Stream-ähnlichen Datentyp zu erstellen, der seine eigene Syntax erhält, aber diese sind höchst experimentell, wenn überhaupt, und ich werde nicht auf Details eingehen.

Auf jeden Fall wartet Ihr Rückruf nur auf das Ende des Streams, was perfekt zu einem Versprechen passt. Sie müssen nur den Stream einwickeln:

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

Nun können Sie dieses Versprechen erwarten:

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

Wenn Sie die Knotenversion> = v10.0.0 verwenden, können Sie stream.pipeline und util.promisify verwenden.

const fs = require('fs');
const crypto = require('crypto');
const util = require('util');
const stream = require('stream');

const pipeline = util.promisify(stream.pipeline);

const hash = crypto.createHash('sha1');
hash.setEncoding('hex');

async function run() {
  await pipeline(
    fs.createReadStream('/some/file/name.txt'),
    hash
  );
  console.log('Pipeline succeeded');
}

run().catch(console.error);
4
shusson

So etwas funktioniert:

for (var res of fetchResponses){ //node-fetch package responses
    const dest = fs.createWriteStream(filePath,{flags:'a'});
    totalBytes += Number(res.headers.get('content-length'));
    await new Promise((resolve, reject) => {
        res.body.pipe(dest);
        res.body.on("error", (err) => {
            reject(err);
        });
        dest.on("finish", function() {
            resolve();
        });
    });         
}
1
Ron Royston