Commençons par expliquer comment les données sont envoyées sur le Web. Il n’est pas envoyé sous forme d’un seul flux continu ; au lieu de cela, il est divisé en morceaux plus petits. Du côté de la réception, le consommateur ou l'application est responsable du réassemblage de ces morceaux dans le bon ordre et dans le bon format une fois que toutes les données ont été reçues. Ce processus se produit automatiquement pour les images, les vidéos et autres types de données relativement volumineux.
Donc, ce que propose l'API Streams est un moyen de, au lieu d'attendre que vos données complètes soient disponibles
Texte révisé : "Ce que propose l'API Streams, c'est un moyen de gérer les données au fur et à mesure qu'elles arrivent, plutôt que d'attendre que l'ensemble de données soit disponible dans son intégralité. Voici deux avantages clés :
Commençons par comparer la méthode traditionnelle de réception de données à l'aide de l'API Fetch avec la nouvelle approche de l'API Streams.
fetch("url") .then((response) => { // Note that there is a middle step before we receive the final data // Let's see what we actually receive console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data });
Dans cet exemple, Response.body est un objet ReadableStream :
ReadableStream { locked: false, state: 'readable', supportsBYOB: true }
Ici, nous rencontrons le premier composant de l'API Streams : ReadableStream. Le constructeur ReadableStream crée et renvoie un objet stream lisible, ce qui nous permet de gérer plus efficacement les données en streaming. Nous pouvons utiliser ce constructeur pour gérer les données en morceaux plutôt que d'attendre que l'ensemble de données soit disponible.
{ arrayBuffer(): Promise; blob(): Promise ; formData(): Promise ; json(): Promise ; text(): Promise ; }
Nous devons implémenter une fonction qui gère l'objet pour accéder aux données telles qu'elles sont envoyées en temps réel. Cette fonction devrait :
1 Recevez le ReadableStream comme une promesse.
Plonger dans ReadableStream
interface ReadableStream{ readonly locked: boolean; cancel(reason?: any): Promise ; getReader(options: { mode: "byob" }): ReadableStreamBYOBReader; getReader(): ReadableStreamDefaultReader ; getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader ; pipeThrough ( transform: ReadableWritablePair , options?: StreamPipeOptions ): ReadableStream ; pipeTo( destination: WritableStream , options?: StreamPipeOptions ): Promise ; tee(): [ReadableStream , ReadableStream ]; }
interface ReadableStreamDefaultReaderextends ReadableStreamGenericReader { read(): Promise >; releaseLock(): void; }
Pour travailler avec le flux, nous utilisons getReader() qui renvoie un ReadableStreamDefaultReader.
Voici un exemple où nous faisons une requête à l'API de Lichess.org pour des jeux au format PGN (considérez-le comme du texte) pour un certain utilisateur. Le résultat final doit être sous forme de texte.
fetch("https://lichess.org/api/games/user/gg").then((response) => { console.log(response); const readablestream = response.body; console.log(readablestream); const reader = readablestream.getReader(); console.log(reader); });
Sortir:
ReadableStream { locked: false, state: 'readable', supportsBYOB: true } ReadableStreamDefaultReader { stream: ReadableStream { locked: true, state: 'readable', supportsBYOB: true }, readRequests: 0, close: Promise {} }
notez que vous ne pouvez pas avoir plusieurs lecteurs en même temps car getReader() générera une erreur si ReadableStream.locked = true, donc si vous souhaitez changer de lecteur, vous devez d'abord libérer le verrou en utilisant ReadableStreamDefaultReader. releaseLock()
fetch("https://lichess.org/api/games/user/gg").then((response) => { const readablestream = response.body; console.log(readablestream); const reader = readablestream.getReader(); console.log(reader); try { reader.releaseLock(); const reader2 = readablestream.getReader(); // won't throw an error const reader3 = readablestream.getReader(); // will throw an error } catch (e) { console.error(e.message); // Invalid state: ReadableStream is locked } });
maintenant nous utilisons la fonction read à l'intérieur du lecteur qui a deux variables
let string = result.push( value.reduce((p, c) => { return p c.fromCharCode(); }, "") ); // or let string = new TextDecoder().decode(value); // both achieve the same thing converting Uint8Array to string
Exemple de code complet
fetch("https://lichess.org/api/games/user/gg") .then((response) => { return new Promise((resolve, reject) => { const readablestream = response.body; const reader = readablestream.getReader(); let result = []; reader.read().then(function handlechunks({ done, value }) { if (done) { resolve(result); return; } const pgn = new TextDecoder().decode(value); result.push(pgn); reader.read().then(handlechunks); }); }); }) .then((result) => { console.log(result); });
// console.log(value) Uint8Array(551) [ 91, 69, 118, 101, 110, 116, 32, 34, 82, 97, 116, 101, 100, 32, 98, 108, 105, 116, 122, 32, 103, 97, 109, 101, 34, 93, 10, 91, 83, 105, 116, 101, 32, 34, 104, 116, 116, 112, 115, 58, 47, 47, 108, 105, 99, 104, 101, 115, 115, 46, 111, 114, 103, 47, 90, 122, 78, 66, 90, 119, 100, 71, 34, 93, 10, 91, 68, 97, 116, 101, 32, 34, 50, 48, 50, 48, 46, 48, 49, 46, 49, 48, 34, 93, 10, 91, 87, 104, 105, 116, 101, 32, 34, 86, 101, 101, 118, 101, 101, 50, ... 451 more items ] // console.log(new TextDecoder().decode(value)) [Event "Rated blitz game"] [Site "https://lichess.org/ZzNBZwdG"] [Date "2020.01.10"] [White "Veevee222"] [Black "gg"] [Result "0-1"] [UTCDate "2020.01.10"] [UTCTime "20:21:02"] [WhiteElo "1858"] [BlackElo "1863"] [WhiteRatingDiff "-6"] [BlackRatingDiff " 35"] [Variant "Standard"] [TimeControl "180 0"] [ECO "C00"] [Termination "Normal"]
1. e4 e6 2. d4 d6 3. c4 Nf6 4. Nc3 c5 5. f4 cxd4 6. Qxd4 Nc6 7. Qd1 b6 8. g3 Bb7 9. Bg2 Rc8 10. Nf3 Be7 11. O-O O-O 12. b3 Nb4 13. Bb2 a5 14. Re1 Qc7 15. a3 Na6 16. Rc1 Nc5 17. Qd4 Nxb3 18. Qd1 Nxc1 19. e5 0-1
par exemple, lien
par exemple, code complet go
Désormais, nous pouvons accéder aux PGN des jeux au fur et à mesure de leur envoi sur le réseau. Par exemple, si nous utilisons les jeux chargés dans l’interface utilisateur d’un site Web, l’utilisateur n’aura pas à attendre devant un écran vide ou de chargement jusqu’à ce que tous les jeux soient chargés. Au lieu de cela, les données peuvent être affichées progressivement, ce qui est bien mieux du point de vue UX.
par exemple, le code complet va ici
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3