In https://stackoverflow.com/a/18658613/779159 finden Sie ein Beispiel für die Berechnung des MD5 einer Datei mithilfe der integrierten Kryptobibliothek und der integrierten 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 oben gezeigten Rückruf zu verwenden, aber dennoch die Effizienz der Verwendung von Streams beizubehalten?
javascript
node.js
async-await
ecmascript-2017
user779159
quelle
quelle
async/await
ist nichts anderes als Unterstützung auf Syntaxebene für Versprechen. Wenn Sie diesen Code in ein Versprechen einfügen können, sind Sie fertig.for-await-of
das Lesen von Streams ( nodejs.org/docs/latest-v10.x/api/… ), aber ich denke, es ist nicht das richtige Konzept für Ihre Frage hier. Lassen Sie es als Notiz für andere, die hierher kommen könnten, in einer Situation, in der es helfen würde.Antworten:
async
Ichawait
arbeite nur mit Versprechungen, nicht mit Streams. Es gibt Ideen, einen zusätzlichen Stream-ähnlichen Datentyp zu erstellen, der eine eigene Syntax erhält, aber diese sind, wenn überhaupt, sehr experimentell 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üssten nur den Stream einpacken:
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` });
Jetzt können Sie dieses Versprechen abwarten:
(async function() { let sha1sum = await end; console.log(sha1sum); }());
quelle
end
? Würde das Versprechen nicht aufgelöst, bevor die Hash-Funktion die Daten ausführen kann? Oder würde es zumindest nicht eine Rennbedingung schaffen? Ich würde annehmen, dass Sie den Wert vonfd.pipe(hash)
in einer Variablen speichern und auf dasfinish
Ereignis warten möchten, da dies signalisieren würde, dass der WriteableStream (Hashing) abgeschlossen ist.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);
quelle
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(); }); }); }
quelle