‫- : Très bien, maintenant travaillons avec les flux.
‫Et encore, en commençant par créer un nouveau fichier.
‫D'accord. Disons maintenant que pour
‫une raison quelconque dans notre application, nous devons lire un gros fichier texte
‫à partir du système de fichiers, puis l'envoyer au client.
‫Alors, comment ferions-nous cela?
‫Eh bien, il existe plusieurs façons et nous allons
‫en explorer quelques-unes en commençant par la plus
‫basique et en allant jusqu'à la meilleure façon de le faire.
‫D'accord, la première chose à faire est d'exiger le package
‫du système de fichiers comme avant, ainsi que le module HTTP.
‫Permettez-moi maintenant de vous montrer une astuce intéressante, alors
‫créons en fait un serveur comme celui-ci.
‫Donc, exigez le package HTTP, puis à partir de là,
‫nous pouvons immédiatement appeler createServer. Alors juste comme ça.
‫D'accord, donc le résultat de l'exigence de HTTP est l'objet
‫HTTP et là-bas, nous pouvons ensuite utiliser createServer.
‫Juste comme ça, puis enregistrez-le dans une variable.
‫C'est donc une autre façon de créer un nouveau serveur en
‫écrivant encore un peu moins de code.
‫D'accord et comme avant, listons maintenant l'événement
‫de demande et spécifions notre rappel ici.
‫Ainsi, la première solution que nous allons utiliser est
‫la plus simple et la plus directe.
‫Ce qui consiste simplement à lire le fichier dans une variable,
‫puis une fois cela fait, à l'envoyer au
‫client de la manière dont nous savons déjà le faire.
‫Alors celui-là est très simple, et permettez-moi d'écrire
‫un commentaire ici pour cela. Donc solution
‫un, et donc fs. readFile puis à nouveau notre fichier de test.
‫Et puis une fois que c'est prêt, nous appelons notre fonction de
‫rappel dans laquelle nous avons accès aux données.
‫Mais gérons d'abord l'erreur.
‫Donc par exemple dans le cas où le fichier n'existe pas, et
‫dans ce cas on enregistre simplement l'erreur dans la console.
‫Mais sinon, nous renvoyons simplement ces données au client.
‫Nous utilisons donc l'objet de réponse comme nous l'avons
‫fait plusieurs fois auparavant, puis . fin et les données.
‫Alors, faites une sauvegarde, et c'est donc la première et la
‫plus simple des solutions, n'est-ce pas ?
‫Mais avant de pouvoir tester cela, nous devons également démarrer
‫un serveur, n'est-ce pas ? Nous utilisons donc listen pour le faire.
‫Et le port, le même qu'avant, puis localhost et notre
‫fonction de rappel.
‫Bon, voyons si cela fonctionne réellement.
‫Et bien sûr que non, car je n'ai même pas
‫lancé l'application.
‫Alors maintenant, il est dit d'écouter, et maintenant voyons ce
‫qui se passe ici.
‫Et c'est reparti. Donc ce fichier est énorme,
‫il a Node. js est le mieux écrit dedans,
‫environ 10000 fois ou quelque chose du genre, et il faut donc beaucoup
‫de temps jusqu'à ce qu'il se charge entièrement. Et nous ne sommes pas
‫vraiment intéressés à tout charger, alors arrêtons cela ici et
‫revenons à notre code. Cela fonctionne donc très bien,
‫la solution que nous avons ici dans ce cas, mais
‫le problème est qu'avec cette solution, le nœud
‫devra en fait charger l'intégralité du fichier en
‫mémoire, car ce n'est qu'une fois prêt qu'il pourra
‫envoyer ces données . Maintenant, c'est un problème lorsque le
‫fichier est volumineux, et aussi lorsqu'il y a une tonne de demandes
‫qui arrivent sur votre serveur. Parce que le
‫processus de nœud manquera très rapidement de ressources et que votre
‫application cessera de fonctionner, tout se bloquera et vos utilisateurs ne
‫seront pas satisfaits, croyez-moi. Donc, cette solution ici
‫fonctionne lorsque nous créons simplement quelque chose
‫de petit localement pour nous-mêmes, par exemple.
‫Mais dans une application prête pour la production, vous ne pouvez pas utiliser
‫un morceau de code comme celui-ci. D'accord? Passons donc à notre
‫deuxième solution. Et dans cette
‫solution, nous utiliserons en fait des flux.
‫D'accord, commentons cette partie et passons
‫à la solution numéro deux.
‫Et l'idée ici est que nous n'avons
‫pas vraiment besoin de lire ces données du fichier dans une variable, n'est-ce pas ?
‫Nous n'avons pas besoin de cette variable. Ainsi, au lieu de
‫lire les données dans une variable et de devoir stocker cette
‫variable en mémoire, nous allons simplement créer un flux lisible.
‫Ensuite, au fur et à mesure que nous recevons chaque bloc
‫de données, nous l'envoyons au client en tant
‫que réponse qui est un flux inscriptible à retenir.
‫Alors laissez-moi maintenant vous montrer comment nous pouvons utiliser les flux.
‫Nous créons donc une variable, appelons-la lisible ici, puis à partir
‫du système de fichiers à nouveau, nous utilisons
‫createReadStream Ensuite, bien sûr, petit. Et maintenant le nom du fichier que
‫nous essayons de lire. C'est donc encore une fois, test-file. SMS.
‫D'accord, parfait. Cela crée donc maintenant un flux à
‫partir des données qui se trouvent dans ce fichier texte, que nous
‫pouvons ensuite consommer pièce par pièce. Donc morceau par morceau.
‫Et comment fait-on ? Eh bien, rappelez-vous
‫de la dernière conférence, qu'à chaque fois qu'il y
‫a une nouvelle donnée que nous pouvons consommer, un flux
‫lisible émet l'événement de données. D'accord, et donc nous pouvons écouter
‫ça, comme nous l'avons appris dans la conférence sur les événements.
‫Tellement lisible. on, data, puis notre fonction de rappel.
‫Et dans notre fonction de rappel, nous avons accès à
‫cette donnée, donc à ce morceau.
‫Permettez-moi de l'appeler morceau ici dans notre
‫fonction de rappel et nous pouvons maintenant gérer cette donnée.
‫Et ce que nous allons
‫faire avec cette donnée, avec ce morceau, c'est en
‫fait l'écrire dans un flux inscriptible, qui est la réponse.
‫Donc, rés. écrire, ce morceau. D'accord?
‫Rappelez-vous donc encore une fois que cette réponse
‫est un flux inscriptible. Comme je l'ai mentionné dans
‫la vidéo précédente, n'est-ce pas ? Et nous pouvons maintenant
‫utiliser la méthode d'écriture pour envoyer chaque élément de données dans ce flux.
‫D'accord, et avec cela, nous diffusons
‫efficacement le contenu du fichier directement vers le client.
‫Bon, tu comprends la différence ?
‫Donc avant, nous écrivions tout d'un coup dans une variable, et
‫une fois que c'était prêt, nous renvoyions ensuite toute
‫cette donnée au client. Mais dans cette
‫situation, avec le stream, c'est différent.
‫Nous diffusons effectivement le fichier en continu, nous lisons
‫donc une partie du fichier et dès
‫qu'elle est disponible, nous l'envoyons directement au client, en utilisant la méthode d'écriture
‫du flux de réponse. Ensuite, lorsque la pièce
‫suivante est disponible, cette pièce sera envoyée, et tout le
‫chemin jusqu'à ce que l'intégralité du fichier soit lu et diffusé au client.
‫Bon, maintenant juste pour finir, nous devons également gérer
‫l'événement lorsque toutes les données sont lues.
‫Ainsi, lorsque le flux a essentiellement fini de lire les
‫données du fichier.
‫Donc, dans ce cas, l'événement de fin
‫sera émis, et dès que cela se produira, nous
‫allons faire res. fin, d'accord ? Et nous avons utilisé celui-ci
‫avant, donc appeler la fin de la réponse, nous l'avons fait avant, n'est-ce pas ?
‫Et maintenant, cela a en fait plus de sens, car encore
‫une fois, la réponse est également un flux, et la
‫méthode end signale qu'aucune autre donnée ne sera écrite
‫dans ce flux inscriptible, d'accord ?
‫Donc, ici, tout ce que nous avons fait était d'utiliser res. terminer avec les données
‫qu'il contient. Nous n'avons donc pas fait
‫de streaming, nous n'avons finalement fait qu'envoyer des données.
‫Maintenant, dans ce cas, nous ne transmettons
‫rien à cette méthode de fin, car nous avons déjà envoyé toutes les
‫données à l'aide de res. écrire, morceau par morceau,
‫et donc lorsque le flux lisible a fini de
‫lire son fichier, eh bien, tout ce que nous avons à faire est de
‫signaler que nous sommes prêts en utilisant res. finir comme ça, d'accord ?
‫Nous devons donc toujours utiliser ces données et cet événement final ici l'un
‫après l'autre comme ceci. Car sinon,
‫la réponse ne sera en fait jamais
‫vraiment envoyée au client. D'accord, donc sans cette pièce
‫ici, toute cette solution ne fonctionnerait pas vraiment, d'accord ?
‫Alors maintenant, fermez celui-ci, recommencez et relisez,
‫et vous verrez que cela fonctionne à
‫nouveau, d'accord ? Maintenant cette fois sans les problèmes que nous
‫avions avec la première solution. Arrêtons cela ici et revenons
‫à notre code, car je veux vous montrer
‫maintenant qu'il existe un autre événement que nous
‫pouvons écouter sur un flux lisible, qui est l'événement d'erreur.
‫Tellement lisible. on('error') et dans cette fonction de
‫rappel, nous avons accès à l'objet d'erreur.
‫Bon, dans ce cas, nous allons enregistrer cette erreur sur
‫la console, puis envoyer le résultat du fichier introuvable.
‫Et on peut aussi mettre le code d'état sur une
‫erreur, donc 500 par exemple. Donc, généralement, il est automatiquement défini
‫sur 200, ce qui signifie que d'accord, mais dans ce cas, nous avons une erreur
‫de serveur, ce qui signifie que nous voulons renvoyer le code 500.
‫Très bien, alors allons maintenant...
‫En fait, je dois à nouveau arrêter ça.
‫Voyons donc ce qui se passe maintenant.
‫Oh, nous avons déjà une erreur
‫ici, res. le statut n'est pas une fonction. Et oui,
‫en fait son statusCode. C'est donc ainsi
‫que vous l'écrivez dans express, donc je suis déjà habitué à écrire
‫tellement express, donc express est un nœud. js que nous allons utiliser dans le
‫reste du cours et dans
‫express vous le faites comme ça, et c'était
‫donc le problème. Je suis donc déjà un peu trop
‫habituée à écrire en express.
‫Alors revenons en arrière, et oui, maintenant nous voyons le fichier introuvable, et
‫si nous ouvrons les outils de développement, vous voyez notre code d'erreur 500 que nous
‫venons d'envoyer auparavant, et si nous allons dans notre onglet réseau,
‫essayons à nouveau, vous avez également le code d'état ici.
‫Donc, tout comme nous l'avons vu dans l'une des vidéos précédentes dans une
‫autre section en fait. Voici donc comment nous pouvons
‫inspecter ce genre de choses dans l'onglet réseau.
‫Très bien, réparons-le ici, sauvegardons-le, et d'accord, cela fonctionne à
‫nouveau parfaitement, mais il y a toujours un problème avec
‫cette approche que je viens de
‫vous montrer. Et le problème est
‫que notre flux lisible, donc celui que nous
‫utilisons pour lire le fichier à partir du disque, est beaucoup plus
‫rapide que d'envoyer le résultat avec le flux inscriptible
‫de réponse sur le réseau. Et cela submergera le flux
‫de réponse, qui ne peut pas gérer toutes ces données entrantes si rapidement.
‫Et ce problème s'appelle la contre-pression.
‫Et c'est un vrai problème qui peut arriver dans des situations réelles.
‫Donc, dans ce cas, la contre-pression se produit lorsque la réponse ne
‫peut pas envoyer les données presque aussi vite qu'elle les reçoit du fichier,
‫est-ce que cela a du sens ?
‫Nous devons donc corriger cette
‫solution et en trouver une encore meilleure.
‫Et donc, nous allons créer la solution
‫trois, et c'est en fait la
‫dernière, d'accord ? Donc pas plus de solutions que trois.
‫Donc le secret ici est d'utiliser cet opérateur de tuyau que j'ai
‫mentionné dans la dernière vidéo, d'accord ?
‫L'opérateur pipe est donc disponible sur tous les flux lisibles, et il
‫nous permet de diriger la sortie d'un flux
‫lisible directement dans l'entrée d'un flux inscriptible, d'accord ?
‫Et cela résoudra ensuite le problème de contre-pression
‫car il gérera automatiquement la vitesse
‫des données entrantes et la vitesse des données sortantes.
‫D'accord, obtenons en fait notre flux lisible ici.
‫D'accord, c'est donc notre flux lisible, et maintenant
‫tout ce que nous avons à faire est de prendre notre
‫flux lisible, d'utiliser la méthode pipe dessus, puis de mettre un flux inscriptible
‫et c'est la réponse. Et c'est en fait ça.
‫C'est tout ce que nous avons à faire pour cette solution, d'accord ?
‫Donc ça marche toujours comme ça,
‫laissez-moi l'écrire ici en commentaire. Nous avons donc besoin d'une source lisible en
‫gros, d'accord, encore une fois, c'est juste pour vous l'expliquer,
‫puis nous pouvons utiliser le tuyau dessus, et ici nous
‫devrons mettre une destination en écriture. C'est donc de là que proviennent
‫nos données, et il doit s'agir d'un flux
‫lisible, et nous pouvons ensuite diriger ces données vers une destination accessible en écriture.
‫Donc, dans ce cas, notre destination est la réponse, d'accord ?
‫Maintenant, ce flux ici peut également être un duplex ou un
‫flux de transformation, mais ce qui compte, c'est que nous
‫puissions écrire dans le flux. Et la réponse, bien
‫sûr, est un tel flux. Donc on peut bien sûr écrire
‫à la réponse qui sera envoyée au client, d'accord ?
‫Ainsi, l'opérateur de canalisation résout automatiquement le problème
‫de contre-pression que nous avions auparavant.
‫Et c'est aussi en fait une solution beaucoup
‫plus élégante et simple. Donc, ce que nous
‫avons fait ici auparavant était juste de vous montrer toutes
‫les manières dont nous pouvons utiliser les méthodes et les événements de flux afin
‫de créer ce type de solution et bien sûr, ils ont
‫de nombreux cas d'utilisation, mais dans un problème comme celui-ci, le tuyau
‫opérateur est en fait la meilleure solution. Dans les coulisses, il fait quelque
‫chose comme ça ici en fait,
‫mais encore une fois d'une manière beaucoup plus simple pour
‫nous d'écrire, car il gère tout en
‫interne dans les coulisses. Je pense donc que le pipe ici
‫est en fait le moyen le plus simple de consommer et d'écrire des flux,
‫à moins bien sûr, comme je l'ai mentionné, que nous ayons
‫besoin de solutions plus personnalisées. Et puis, nous devons
‫utiliser ces outils plus compliqués comme ces événements et méthodes
‫que je vous ai montrés auparavant. Très bien, donc
‫juste pour finir, quittons le processus ici, redémarrez-le, et bien sûr, voyons
‫si cela fonctionne toujours, ce qui est le cas.
‫Et donc, notre travail est fait ici. Nous avons donc terminé cette
‫conférence et prêts à passer directement à la suivante.