Comencemos explicando cómo se envían los datos a través de la web. No se envía como un único flujo continuo; en cambio, se divide en trozos más pequeños. En el lado receptor, el consumidor o la aplicación es responsable de volver a ensamblar estos fragmentos en el orden y formato correctos una vez que se hayan recibido todos los datos. Este proceso ocurre automáticamente para imágenes, videos y otros tipos de datos relativamente grandes.
Entonces, lo que ofrece Streams API es una forma de, en lugar de esperar a que todos tus datos estén disponibles
Texto revisado: "Lo que ofrece Streams API es una forma de manejar los datos a medida que llegan, en lugar de esperar a que todo el conjunto de datos esté disponible. Aquí hay dos beneficios clave:
Comencemos comparando el método tradicional de recibir datos usando Fetch API con el nuevo enfoque de Streams API.
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 });
En este ejemplo, respuesta.body es un objeto ReadableStream:
ReadableStream { locked: false, state: 'readable', supportsBYOB: true }
Aquí nos encontramos con el primer componente de la API Streams: ReadableStream. El constructor ReadableStream crea y devuelve un objeto de transmisión legible, lo que nos permite manejar la transmisión de datos de manera más eficiente. Podemos usar este constructor para administrar datos en fragmentos en lugar de esperar a que todo el conjunto de datos esté disponible.
{ arrayBuffer(): Promise; blob(): Promise ; formData(): Promise ; json(): Promise ; text(): Promise ; }
Necesitamos implementar una función que maneje el objeto para acceder a los datos a medida que se envían en tiempo real. Esta función debería:
1 Reciba ReadableStream como promesa.
Sumergiendo en 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; }
Para trabajar con la transmisión, usamos getReader() que devuelve un ReadableStreamDefaultReader.
Aquí hay un ejemplo en el que realizamos una solicitud a la API de Lichess.org para juegos en formato PGN (considérelo como texto) para un determinado usuario. El resultado final debe estar en texto.
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); });
Producción:
ReadableStream { locked: false, state: 'readable', supportsBYOB: true } ReadableStreamDefaultReader { stream: ReadableStream { locked: true, state: 'readable', supportsBYOB: true }, readRequests: 0, close: Promise {} }
tenga en cuenta que no puede tener varios lectores al mismo tiempo, ya que getReader() arrojará un error si ReadableStream.locked = true, por lo que si desea cambiar el lector, primero debe liberar el bloqueo usando ReadableStreamDefaultReader. liberarBloqueo()
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 } });
ahora usamos la función de lectura dentro del lector que tiene dos 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
Ejemplo de código completo
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
por ejemplo enlace
por ejemplo, código completo ir
Ahora podremos acceder a los PGN de los juegos de forma progresiva a medida que se envían a través de la red. Por ejemplo, si utilizamos los juegos cargados en la interfaz de usuario de un sitio web, el usuario no tendrá que esperar frente a una pantalla en blanco o de carga hasta que se carguen todos los juegos. En cambio, los datos se pueden mostrar progresivamente, lo cual es mucho mejor desde el punto de vista de UX.
por ejemplo, el código completo va aquí
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3