verwandeln
Transformations-Streams sind sowohl lesbar als auch beschreibbar und daher wirklich gute "mittlere" Streams. Aus diesem Grund werden sie manchmal als through
Streams bezeichnet. Sie ähneln auf diese Weise einem Duplex-Stream, bieten jedoch eine schöne Schnittstelle zum Bearbeiten der Daten, anstatt sie nur zu senden. Der Zweck eines Transformationsstroms besteht darin, die Daten zu manipulieren, während sie durch den Strom geleitet werden. Möglicherweise möchten Sie beispielsweise einige asynchrone Aufrufe ausführen oder einige Felder ableiten, einige Dinge neu zuordnen usw.
Informationen zum Erstellen eines Transformations-Streams finden Sie hier und hier . Alles was du tun musst, ist :
- Fügen Sie das Stream-Modul hinzu
- Instanziieren (oder erben) der Transform-Klasse
- Implementieren Sie eine
_transform
Methode, die a (chunk, encoding, callback)
.
Der Block sind Ihre Daten. Die meiste Zeit müssen Sie sich keine Gedanken über die Codierung machen, wenn Sie arbeiten objectMode = true
. Der Rückruf wird aufgerufen, wenn Sie mit der Verarbeitung des Blocks fertig sind. Dieser Block wird dann zum nächsten Stream weitergeleitet.
Wenn Sie ein nettes Hilfsmodul möchten, mit dem Sie ganz einfach Streams durchführen können, empfehle ich through2 .
Lesen Sie zur Fehlerbehandlung weiter.
Rohr
In einer Rohrkette ist die Behandlung von Fehlern in der Tat nicht trivial. Laut diesem Thread ist .pipe () nicht dafür ausgelegt, Fehler weiterzuleiten. Also so etwas wie ...
var a = createStream();
a.pipe(b).pipe(c).on('error', function(e){handleError(e)});
... würde nur auf Fehler im Stream warten c
. Wenn ein Fehlerereignis ausgegeben a
würde, würde dieses nicht weitergegeben und würde tatsächlich werfen. Um dies richtig zu machen:
var a = createStream();
a.on('error', function(e){handleError(e)})
.pipe(b)
.on('error', function(e){handleError(e)})
.pipe(c)
.on('error', function(e){handleError(e)});
Obwohl der zweite Weg ausführlicher ist, können Sie zumindest den Kontext beibehalten, in dem Ihre Fehler auftreten. Dies ist normalerweise eine gute Sache.
Eine Bibliothek, die ich jedoch hilfreich finde, wenn Sie einen Fall haben, in dem Sie nur die Fehler am Ziel erfassen möchten und sich nicht so sehr darum kümmern, wo es passiert ist, ist der Ereignisstrom .
Ende
Wenn ein Fehlerereignis ausgelöst wird, wird das Endereignis nicht (explizit) ausgelöst. Das Ausgeben eines Fehlerereignisses beendet den Stream.
Domänen
Nach meiner Erfahrung funktionieren Domains die meiste Zeit sehr gut. Wenn Sie ein nicht behandeltes Fehlerereignis haben (dh einen Fehler in einem Stream ohne Listener ausgeben), kann der Server abstürzen. Wie im obigen Artikel ausgeführt, können Sie den Stream jetzt in eine Domäne einschließen, die alle Fehler ordnungsgemäß abfangen sollte.
var d = domain.create();
d.on('error', handleAllErrors);
d.run(function() {
fs.createReadStream(tarball)
.pipe(gzip.Gunzip())
.pipe(tar.Extract({ path: targetPath }))
.on('close', cb);
});
Das Schöne an Domänen ist, dass sie die Stapelspuren beibehalten. Auch wenn Event-Stream gute Arbeit leistet.
Weitere Informationen finden Sie im Stream-Handbuch . Ziemlich ausführlich, aber sehr nützlich und bietet einige großartige Links zu vielen hilfreichen Modulen.
Promise
Frameworks machen es viel einfacher