Давайте начнем с объяснения того, как данные передаются через Интернет. Он не отправляется как единый непрерывный поток; вместо этого он делится на более мелкие куски. На принимающей стороне потребитель или приложение несет ответственность за повторную сборку этих фрагментов в правильном порядке и формате после получения всех данных. Этот процесс происходит автоматически для изображений, видео и других относительно больших типов данных.
Итак, API Streams предлагает способ вместо ожидания доступности полных данных
Измененный текст: «API Streams предлагает способ обработки данных по мере их поступления, а не ожидание доступности всего набора данных. Вот два ключевых преимущества:
Давайте начнем со сравнения традиционного метода получения данных с помощью Fetch API с новым подходом 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 });
В этом примере response.body является объектом ReadableStream:
ReadableStream { locked: false, state: 'readable', supportsBYOB: true }
Здесь мы встречаем первый компонент Streams API: ReadableStream. Конструктор ReadableStream создает и возвращает читаемый объект потока, который позволяет нам более эффективно обрабатывать потоковые данные. Мы можем использовать этот конструктор для управления данными порциями, а не ждать, пока станет доступен весь набор данных.
{ arrayBuffer(): Promise; blob(): Promise ; formData(): Promise ; json(): Promise ; text(): Promise ; }
Нам нужно реализовать функцию, которая обрабатывает объект для доступа к данным по мере их отправки в реальном времени. Эта функция должна:
1 Получите ReadableStream как обещание.
Погружение в 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; }
Для работы с потоком мы используем getReader(), который возвращает ReadableStreamDefaultReader.
Вот пример, где мы делаем запрос к API Lichess.org для игр в формате PGN (представьте, что это текст) для определенного пользователя. Конечный результат должен быть в текстовом виде.
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); });
Выход:
ReadableStream { locked: false, state: 'readable', supportsBYOB: true } ReadableStreamDefaultReader { stream: ReadableStream { locked: true, state: 'readable', supportsBYOB: true }, readRequests: 0, close: Promise {} }
обратите внимание, что вы не можете иметь несколько читателей одновременно, так как getReader() выдаст ошибку, если ReadableStream.locked = true, поэтому, если вы хотите изменить читателя, вам нужно сначала снять блокировку с помощью ReadableStreamDefaultReader. релизLock()
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 } });
теперь мы используем функцию чтения внутри средства чтения, которая имеет две переменные
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
Полный пример кода
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
например ссылка
например, полный код
Теперь мы можем получать доступ к PGN игр постепенно по мере их отправки через сеть. Например, если мы используем загруженные игры в пользовательском интерфейсе веб-сайта, пользователю не придется ждать перед пустым экраном или экраном загрузки, пока все игры не загрузятся. Вместо этого данные могут отображаться постепенно, что намного лучше с точки зрения UX.
например, полный код здесь
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3