Maîtriser les flux de données sous Node : partie 1

Roly Fentanes

Traducteur

vermine

Roly Fentanes est un développeur de logiciels qui apprécie travailler avec le JavaScript et particulièrement avec Node.js. Il a d'ailleurs créé plusieurs plugins. Aujourd'hui il désire nous apprendre à maîtriser efficacement les flux de données avec Node.js.
Cet article est la traduction de Mastering Node Streams: Part 1 publié sur DailyJS.
Commentez

- Titre : Maîtriser les flux de données sous Node : partie 1

- Auteur : Roly Fentanes

- Traducteur : vermine

- Parution : 10 septembre 2012

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2012 Roly Fentanes. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Avant-propos

- II. Modèle courant

- III. Supporter d'autres flux

- IV. Streamin

- V. La suite

- VI. Remerciements

I - Avant-propos

Les flux sont un des types de données les moins utilisés sous Node. Si vous êtes à l'aise avec Node, vous avez probablement entendu cela auparavant. Mais à force de voir plusieurs nouveaux modules de pop-up qui ne profitent pas des avantages des flux, ou, qui n'utilisent pas pleinement leur potentiel, je ressens le besoin de partager mes connaissances à ce sujet.

II - Modèle courant

Le modèle courant que je vois dans les modules nécessitant des flux en entrée est le suivant :

var foo = require('foo');

foo('/chemin/de/mon_fichier', function onResult(err, resultats) {
// utilisation du résultat
});

En ayant uniquement un chemin d'accès à un fichier comme point d'entrée de votre module, vous limitez le flux que le module pourrait utiliser à un fichier accessible en lecture dont vous n'avez aucun contrôle.

III - Supporter d'autres flux

On pourrait croire qu'il est très fréquent pour un module de lire un fichier, mais cela ne tient pas compte du fait qu'un flux n'est pas seulement un fichier. Un flux peut être plusieurs choses. Il pourrait être un parseur, une requête HTTP ou un processus enfant. Il existe plusieurs autres possibilités.

Supporter uniquement des chemins d'accès à des fichiers limite les développeurs. Tout autre type de flux doit alors être écrit dans le système de fichiers et puis lu par après, ce qui est moins efficace. Une des raisons est la mémoire supplémentaire qui est nécessaire pour stocker le flux. Deuxièmement, il faut plus de temps pour diffuser le fichier sur le disque et ensuite pour lire les données dont l'utilisateur a besoin.

Pour éviter cela, l'API du module foo ci-dessus doit être écrite de cette façon :

var stream = fs.createReadStream('/chemin/de/mon_fichier');
foo(stream, function onResult(err, resultats) {
// utilisation du résultat
});

Maintenant, l'exemple foo peut prendre n'importe quel type de flux en entrée, y compris un fichier. Cependant, passer un fichier est peut-être trop long. Le module fs est alors requis et un flux plus approprié doit être créé. La solution est de permettre de passer comme paramètre un flux ou bien un chemin d'accès à un fichier :

foo(streamOrPath, function onResult(err, resultats) {
// ...
});

À l'intérieur de foo, on vérifie le type de streamOrPath et on crée un flux si nécessaire :

module.exports = function foo(streamOrPath, callback) {
if (typeof streamOrPath === 'string') {
stream = fs.createReadStream(streamOrPath);
} else if (streamOrPath.pipe && streamOrPath.readable) {
stream = streamOrPath;
} else {
throw new TypeError('foo ne peut être appelé qu\'avec un flux ou un chemin d\'accès');
}

// faire ce que l'on veut avec le flux
};

IV - Streamin

Voilà, c'est vraiment simple, non ? Si simple que j'ai créé un plugin juste pour ce cas d'utilisation courante : streamin.

var streamin = require('streamin');

module.exports = function foo(streamOrPath, callback) {
var stream = streamin(streamOrPath);

// faire ce que l'on veut avec le flux
};

Ne vous laissez pas abuser par son nom, streamin fonctionne également avec des flux de sortie.

V - La suite

Dans la prochaine partie, je vais vous montrer comment les modules de type Request retournent des flux synchrones même lorsqu'ils ne sont pas immédiatement disponibles.

VI - Remerciements

Cet article a été publié avec l'aimable autorisation de Roly Fentanes pour l'article original Mastering Node Streams: Part 1 publié sur le site DailyJS.
Je remercie également Torgar pour sa relecture attentive et assidue.