본문 바로가기
C.W.K.
Stream
Lesson 03 of 05 · published

비동기 이터러블: 도착하는 값을 하나씩 소비하기

~9 min · async-promises, async-iterable, for-await, streaming

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"전체가 끝날 때까지 기다리지 말고, 준비된 조각부터 흐르게 할 수 있어."

AsyncIterable<T>의 뜻

AsyncIterable<T>는 다음 값을 얻는 과정 자체가 비동기인 연속 데이터를 나타내. for await (const item of source)를 쓰면 각 itemT로 추론되고, 반복문은 다음 Promise가 끝날 때까지 기다렸다가 이어져.

일반 배열의 Iterable<T>와 달리 네트워크 스트림, 페이지 단위 조회, 파일 청크처럼 값 사이에 시간이 걸리는 자료에 맞아. 모든 항목을 메모리에 모으지 않고 처리할 수 있다는 점도 중요하지.

비동기 제너레이터 만들기

async function* pages(): AsyncGenerator<Page> 안에서는 yield page로 값을 하나씩 내보내고 await로 다음 자료를 기다릴 수 있어. 소비자가 반복을 멈추면 제너레이터의 finally에서 연결이나 리더를 정리하도록 설계해.

Promise<T[]>와의 차이

Promise<T[]>는 전체 배열이 한 번에 준비되는 하나의 Promise야. AsyncIterable<T>는 값이 하나씩 도착하는 스트림이라 마지막 값이 오기 전부터 첫 값을 처리할 수 있어. 큰 데이터나 느린 생산자에는 스트림이, 작은 일괄 결과에는 Promise 배열이 더 단순해.

비동기 이터러블은 '나중에 한 값'인 Promise를 '시간을 두고 여러 값'으로 확장한 계약이야. 흐름뿐 아니라 종료와 정리까지 API의 일부로 다뤄.

Code

Async iterable — generator 와 Node stream·typescript
// Async generator — 시간이 지나 값 yield.
async function* tickStream(): AsyncIterable<number> {
  for (let i = 0; i < 5; i++) {
    await new Promise((r) => setTimeout(r, 100));
    yield i;
  }
}

// for-await 로 소비.
async function consume() {
  for await (const n of tickStream()) {
    console.log(n);    // n: number, 100ms 마다 출력
  }
}

// fs stream, Node 의 readline, fetch 의 body — 다 async iterable.
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';

async function readLines(path: string) {
  const rl = createInterface({ input: createReadStream(path) });
  for await (const line of rl) {
    console.log(line);   // line: string
  }
}

External links

Exercise

페이지의 다음 커서가 없을 때까지 항목을 내보내는 비동기 제너레이터 paginate를 작성해. 페이지 조회 함수는 커서를 받아 Promise를 반환하게 하고, 완성한 제너레이터를 for await로 소비해 페이지 경계 없이 항목이 이어지는지 확인해.
Hint
현재 커서로 페이지를 기다린 뒤 각 항목을 yield하고 다음 커서로 이동해. 다음 커서가 null이면 멈추므로 소비자는 페이지 구분 없이 항목만 순회할 수 있어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.