transformer
Les flux de transformation sont à la fois lisibles et inscriptibles, et sont donc de très bons flux «intermédiaires». Pour cette raison, ils sont parfois appelés through
flux. Ils sont similaires à un flux duplex de cette manière, sauf qu'ils fournissent une interface agréable pour manipuler les données plutôt que de simplement les envoyer. Le but d'un flux de transformation est de manipuler les données lorsqu'elles sont acheminées dans le flux. Vous voudrez peut-être faire des appels asynchrones, par exemple, ou dériver quelques champs, remapper certaines choses, etc.
Pour savoir comment créer un flux de transformation, voir ici et ici . Tout ce que tu dois faire est :
- inclure le module de flux
- instancier (ou hériter de) la classe Transform
- implémenter une
_transform
méthode qui prend un (chunk, encoding, callback)
.
Le morceau est vos données. La plupart du temps, vous n'aurez pas à vous soucier de l'encodage si vous travaillez objectMode = true
. Le rappel est appelé lorsque vous avez terminé de traiter le bloc. Ce bloc est ensuite poussé vers le flux suivant.
Si vous voulez un bon module d'aide qui vous permettra de faire du stream très facilement, je suggère through2 .
Pour la gestion des erreurs, continuez à lire.
tuyau
Dans une chaîne de tubes, la gestion des erreurs n'est en effet pas triviale. Selon ce fil, .pipe () n'est pas conçu pour transmettre les erreurs. Donc quelque chose comme ...
var a = createStream();
a.pipe(b).pipe(c).on('error', function(e){handleError(e)});
... n'écouterait que les erreurs sur le flux c
. Si un événement d'erreur était émis a
, cela ne serait pas transmis et, en fait, serait déclenché. Pour faire cela correctement:
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)});
Maintenant, bien que la deuxième méthode soit plus verbeuse, vous pouvez au moins conserver le contexte dans lequel vos erreurs se produisent. C'est généralement une bonne chose.
Une bibliothèque que je trouve utile si vous avez un cas où vous souhaitez uniquement capturer les erreurs à la destination et que vous ne vous souciez pas tellement de l'endroit où cela s'est produit est le flux d'événements .
fin
Lorsqu'un événement d'erreur est déclenché, l'événement de fin ne sera pas déclenché (explicitement). L'émission d'un événement d'erreur mettra fin au flux.
domaines
D'après mon expérience, les domaines fonctionnent très bien la plupart du temps. Si vous avez un événement d'erreur non géré (c'est-à-dire émettant une erreur sur un flux sans écouteur), le serveur peut planter. Maintenant, comme le souligne l'article ci-dessus, vous pouvez envelopper le flux dans un domaine qui devrait correctement détecter toutes les erreurs.
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);
});
- l'exemple de code ci-dessus provient de ce post
La beauté des domaines est qu'ils conserveront les traces de la pile. Bien que le flux d'événements fasse également un bon travail dans ce domaine.
Pour plus d'informations, consultez le manuel du flux . Assez en profondeur, mais super utile et donne d'excellents liens vers de nombreux modules utiles.
Promise
les frameworks le rendent beaucoup plus simple