Erläutern wir zunächst, wie Daten über das Web gesendet werden. Es wird nicht als einzelner kontinuierlicher Stream gesendet; Stattdessen wird es in kleinere Stücke aufgeteilt. Auf der Empfängerseite ist der Verbraucher oder die Anwendung dafür verantwortlich, diese Blöcke in der richtigen Reihenfolge und im richtigen Format wieder zusammenzusetzen, sobald alle Daten empfangen wurden. Dieser Vorgang erfolgt automatisch für Bilder, Videos und andere relativ große Datentypen.
Die Streams-API bietet also eine Möglichkeit, anstatt darauf zu warten, dass Ihre vollständigen Daten verfügbar sind
Überarbeiteter Text: „Die Streams-API bietet eine Möglichkeit, Daten direkt bei ihrem Eintreffen zu verarbeiten, anstatt darauf zu warten, dass der gesamte Datensatz verfügbar ist. Hier sind zwei Hauptvorteile:
Beginnen wir mit dem Vergleich der herkömmlichen Methode zum Empfangen von Daten mithilfe der Fetch-API mit dem neuen Streams-API-Ansatz.
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 });
In diesem Beispiel ist Response.body ein ReadableStream-Objekt:
ReadableStream { locked: false, state: 'readable', supportsBYOB: true }
Hier treffen wir auf die erste Komponente der Streams-API: ReadableStream. Der ReadableStream-Konstruktor erstellt ein lesbares Stream-Objekt und gibt es zurück, wodurch wir Streaming-Daten effizienter verarbeiten können. Mit diesem Konstruktor können wir Daten in Blöcken verwalten, anstatt darauf zu warten, dass der gesamte Datensatz verfügbar ist.
{ arrayBuffer(): Promise; blob(): Promise ; formData(): Promise ; json(): Promise ; text(): Promise ; }
Wir müssen eine Funktion implementieren, die das Objekt verarbeitet, um auf Daten zuzugreifen, während diese in Echtzeit gesendet werden. Diese Funktion sollte:
1 Empfangen Sie den ReadableStream als Versprechen.
Eintauchen in 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; }
Um mit dem Stream zu arbeiten, verwenden wir getReader(), das einen ReadableStreamDefaultReader zurückgibt.
Hier ist ein Beispiel, in dem wir eine Anfrage an die API von Lichess.org für Spiele im PGN-Format (stellen Sie sich das als Text vor) für einen bestimmten Benutzer stellen. Das Endergebnis sollte im Text vorliegen.
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); });
Ausgabe:
ReadableStream { locked: false, state: 'readable', supportsBYOB: true } ReadableStreamDefaultReader { stream: ReadableStream { locked: true, state: 'readable', supportsBYOB: true }, readRequests: 0, close: Promise {} }
Beachten Sie, dass Sie nicht mehrere Leser gleichzeitig haben können, da getReader() einen Fehler auslöst, wenn ReadableStream.locked = true ist. Wenn Sie also den Leser ändern möchten, müssen Sie zuerst die Sperre mit ReadableStreamDefaultReader aufheben. 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 } });
Jetzt verwenden wir die Lesefunktion im Reader, die zwei Variablen hat
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
Vollständiges Codebeispiel
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
zum Beispiel Link
zum Beispiel, vollständiger Code go
Jetzt können wir schrittweise auf die PGNs der Spiele zugreifen, während diese über das Netzwerk gesendet werden. Wenn wir beispielsweise die geladenen Spiele in der Benutzeroberfläche einer Website verwenden, muss der Benutzer nicht vor einem leeren oder Ladebildschirm warten, bis alle Spiele geladen sind. Stattdessen können Daten progressiv angezeigt werden, was aus UX-Sicht viel besser ist.
Den vollständigen Code finden Sie beispielsweise hier
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3