Jak używać ES8 async / wait ze strumieniami?

W https://stackoverflow.com/a/18658613/779159 {[3] } jest przykładem jak obliczyć md5 Pliku za pomocą wbudowanej biblioteki kryptograficznej i strumieni.

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

Ale czy jest to możliwe, aby przekonwertować to za pomocą ES8 async / wait zamiast za pomocą wywołania zwrotnego, jak widać powyżej, ale przy zachowaniu efektywności korzystania ze strumieni?

Author: Felix Kling, 2015-11-08

4 answers

async/await działa tylko z obietnicami, nie ze strumieniami. Istnieją pomysły, aby stworzyć dodatkowy typ danych podobny do strumienia, który miałby własną składnię, ale są one bardzo eksperymentalne, jeśli w ogóle i nie będę wchodzić w szczegóły.

W każdym razie, twoja odpowiedź zwrotna czeka tylko na koniec strumienia, który jest idealny dla obietnicy. Trzeba by tylko zawinąć strumień:

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

Teraz możesz czekać na tę obietnicę:

(async function() {
    let sha1sum = await end;
    console.log(sha1sum);
}());
 104
Author: Bergi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-18 20:32:51

Jeśli używasz wersji węzła > = V10.0.0, możesz użyć strumienia .pipeline i 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);
 55
Author: shusson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-11 23:30:42

Coś takiego działa:

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();
        });
    });         
}
 14
Author: Ronnie Royston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-01 01:21:22

Węzeł V15 ma teraz rurociąg promisfiy w stream/promises . Jest to najczystszy i najbardziej oficjalny sposób.

const { pipeline } = require('stream/promises');

async function run() {
  await pipeline(
    fs.createReadStream('archive.tar'),
    zlib.createGzip(),
    fs.createWriteStream('archive.tar.gz')
  );
  console.log('Pipeline succeeded.');
}

run().catch(console.error);

Wszyscy powinniśmy docenić, jak wiele pracy jest tu zrobione:

  • Przechwytywanie błędów we wszystkich strumieniach.
  • niszcz niedokończone strumienie, gdy pojawi się błąd.
  • zwraca tylko wtedy, gdy ostatni zapisywalny strumień jest zakończony.

Ta rura jest jednym z najpotężniejszych węzłów funkcyjnych.JS ma. Zapewnienie pełnej asynchronizacji nie jest łatwe. Teraz to mamy.

 1
Author: Jason Ching,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-28 14:37:28