"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Streams API가 웹 개발자의 판도를 바꾸는 이유

Streams API가 웹 개발자의 판도를 바꾸는 이유

2024-11-08에 게시됨
검색:913

웹을 통해 데이터가 전송되는 방식을 설명하는 것부터 시작하겠습니다. 단일 연속 스트림으로 전송되지 않습니다. 대신에 더 작은 덩어리로 나누어집니다. 수신측에서는 모든 데이터가 수신되면 소비자 또는 애플리케이션이 이러한 청크를 올바른 순서와 형식으로 재조립하는 일을 담당합니다. 이 프로세스는 이미지, 비디오 및 기타 상대적으로 큰 데이터 유형에 대해 자동으로 수행됩니다.

Why the Streams API is a Game-Changer for Web Developers

따라서 Streams API가 제공하는 것은 전체 데이터를 사용할 수 있을 때까지 기다리지 않고 사용할 수 있는 방법입니다.

  1. 소비자 단계에서 데이터를 청크로 수신하여 실시간으로 처리하는데, 이는 이 글에서 보여드릴 예시와 같이 대용량 데이터를 처리할 때 매우 유용하고 경계선에 있는 필수입니다.
  2. 또한 특정 유형의 청크를 전송하려는 경우 백엔드 측에서, 네트워크를 통해 대용량 파일을 전송하기 위해 유사한 작업자를 사용할 때 프런트엔드에서 데이터를 스트림으로 처리할 수 있습니다."

수정된 텍스트: "Streams API가 제공하는 것은 전체 데이터세트가 사용 가능해질 때까지 기다리지 않고 데이터가 도착하자마자 처리하는 방법입니다. 다음은 두 가지 주요 이점입니다.

  1. 실시간 데이터 처리: 데이터를 청크로 수신하면서 실시간으로 처리할 수 있습니다. 이 기능은 이 기사에서 설명할 예와 같이 대량의 데이터를 처리할 때 매우 중요합니다. (이 글은 첫 번째 부분에 초점을 맞추고 있습니다.)
  2. 스트림 기반 데이터 관리: Streams API를 사용하면 데이터를 연속 스트림으로 처리할 수 있습니다. 이는 특정 청크로 데이터를 전송하는 백엔드와 웹 작업자를 사용하여 대용량 파일을 효율적으로 업로드하는 프런트엔드에 유용합니다.

Fetch API를 사용하여 데이터를 수신하는 기존 방법과 새로운 Streams API 접근 방식을 비교해 보겠습니다.

Fetch 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을 약속으로 받습니다.

  1. 모든 데이터 청크가 수신될 때까지 기다립니다.
  2. 청크를 전체 데이터 세트에 병합합니다. 완전한 데이터를 약속으로 반환합니다.

Why the Streams API is a Game-Changer for Web Developers

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 ReadableStreamDefaultReader
  extends 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
  }
});

이제 리더 내부에서 두 개의 변수가 있는 읽기 기능을 사용합니다.

  • 값: UintArray에 현재 청크 내용이 있습니다. 각 int를 char로 변환하고 병합하거나 간단히 TextDecoder().decode()를 사용하여 문자열로 변환할 수 있습니다.
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

예: 링크

예: 전체 코드 이동

Why the Streams API is a Game-Changer for Web Developers

이제 게임의 PGN이 네트워크를 통해 전송되면서 점진적으로 액세스할 수 있습니다. 예를 들어 웹 사이트 UI에 로드된 게임을 사용하는 경우 사용자는 모든 게임이 로드될 때까지 빈 화면이나 로딩 화면 앞에서 기다릴 필요가 없습니다. 대신 데이터를 점진적으로 표시할 수 있어 UX 관점에서 훨씬 좋습니다.
예를 들어 전체 코드는 여기로 이동하세요

릴리스 선언문 이 기사는 https://dev.to/anasmustafa123/why-the-streams-api-is-a-game-changer-for-web-developers-1030?1에서 복제됩니다. 침해가 있는 경우, Study_golang에 문의하세요. @163.com 삭제
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3