웹을 통해 데이터가 전송되는 방식을 설명하는 것부터 시작하겠습니다. 단일 연속 스트림으로 전송되지 않습니다. 대신에 더 작은 덩어리로 나누어집니다. 수신측에서는 모든 데이터가 수신되면 소비자 또는 애플리케이션이 이러한 청크를 올바른 순서와 형식으로 재조립하는 일을 담당합니다. 이 프로세스는 이미지, 비디오 및 기타 상대적으로 큰 데이터 유형에 대해 자동으로 수행됩니다.
따라서 Streams API가 제공하는 것은 전체 데이터를 사용할 수 있을 때까지 기다리지 않고 사용할 수 있는 방법입니다.
수정된 텍스트: "Streams API가 제공하는 것은 전체 데이터세트가 사용 가능해질 때까지 기다리지 않고 데이터가 도착하자마자 처리하는 방법입니다. 다음은 두 가지 주요 이점입니다.
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; }
스트림 작업을 위해 ReadableStreamDefaultReader를 반환하는 getReader()를 사용합니다.
다음은 특정 사용자를 위해 PGN 형식(텍스트로 생각) 게임용 Lichess.org API에 요청하는 예입니다. 최종 결과는 텍스트로 제공되어야 합니다.
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 {} }
ReadableStream.locked = true인 경우 getReader()가 오류를 발생시키므로 동시에 여러 판독기를 가질 수 없습니다. 따라서 판독기를 변경하려면 먼저 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 } });
이제 리더 내부에서 두 개의 변수가 있는 읽기 기능을 사용합니다.
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이 네트워크를 통해 전송되면서 점진적으로 액세스할 수 있습니다. 예를 들어 웹 사이트 UI에 로드된 게임을 사용하는 경우 사용자는 모든 게임이 로드될 때까지 빈 화면이나 로딩 화면 앞에서 기다릴 필요가 없습니다. 대신 데이터를 점진적으로 표시할 수 있어 UX 관점에서 훨씬 좋습니다.
예를 들어 전체 코드는 여기로 이동하세요
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3