web-dev-qa-db-fra.com

Comment utiliser ES8 async/wait avec des flux?

In https://stackoverflow.com/a/18658613/779159 est un exemple de calcul du md5 d'un fichier à l'aide de la bibliothèque de cryptage et des flux intégrés.

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

Mais est-il possible de convertir cela en utilisant ES8 async/wait au lieu d'utiliser le rappel comme indiqué ci-dessus, tout en conservant l'efficacité de l'utilisation des flux?

29
user779159

async/await ne fonctionne qu'avec des promesses, pas avec des flux. Il existe des idées pour créer un type de données supplémentaire de type flux, qui aurait sa propre syntaxe, mais celles-ci sont très expérimentales, voire inexistantes, et je n'entrerai pas dans les détails.

Quoi qu'il en soit, votre rappel n'attend que la fin du flux, ce qui convient parfaitement à une promesse. Il vous suffira d'envelopper le flux:

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

Maintenant, vous pouvez attendre cette promesse:

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

Si vous utilisez la version de noeud> = v10.0.0, vous pouvez utiliser stream.pipeline et util.promisify .

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

Quelque chose comme ça marche:

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