async-iteration

1 개의 포스트

립트에는 더 나 (새 탭에서 열림)

현재의 WHATWG 스트림 표준(Web Streams)은 설계된 지 10년이 지나 현대적인 JavaScript 개발 방식과 동떨어져 있으며, 심각한 사용성 및 성능 문제를 안고 있습니다. 비동기 반복문(`for await...of`)이 도입되기 전에 수립된 이 API는 불필요하게 복잡한 리더/라이터 모델과 잠금(locking) 메커니즘에 의존하고 있어, 현대적 언어 기능을 활용한 대안적인 접근 방식을 통해 최대 120배까지 성능을 개선할 수 있다는 것이 핵심 주장입니다. **역사적 배경과 설계의 시대적 한계** - Web Streams 표준은 2014~2016년 사이에 개발되었으며, 이는 JavaScript의 비동기 반복문(`for await...of`)이 등장(2018년)하기 훨씬 전의 일입니다. - 당시에는 비동기 시퀀스를 처리하는 관용적인 방법이 없었기 때문에, 표준은 리더와 라이터를 획득하고 관리하는 독자적인 모델을 구축해야만 했습니다. - 결과적으로 Node.js와 같은 서버 사이드 런타임들은 호환성을 위해 나중에 이 복잡한 표준을 도입하게 되었고, 이는 현대적인 JavaScript 개발 흐름과 충돌하는 원인이 되었습니다. **과도한 상용구 코드와 사용성 저하** - 스트림을 끝까지 읽는 단순한 작업조차 리더 획득, `read()`의 반복 호출, `{ value, done }` 프로토콜 처리, 그리고 `finally` 블록을 통한 명시적인 잠금 해제 등 복잡한 과정을 거쳐야 합니다. - 나중에 비동기 반복문이 지원되기는 했으나, 이는 기존의 복잡한 구조 위에 덧씌워진 형태에 불과하여 BYOB(Bring Your Own Buffer) 같은 세부적인 기능을 제대로 활용할 수 없는 한계가 있습니다. - 개발자들은 여전히 내부의 리더, 잠금, 컨트롤러 구조를 이해해야 하며, 문제 발생 시 추상화 뒤에 숨은 복잡성 때문에 디버깅에 어려움을 겪습니다. **수동 잠금(Locking) 모델의 치명적 결함** - Web Streams는 다중 소비자의 간섭을 막기 위해 독점적 잠금 모델을 사용하지만, 이를 관리하는 방식이 매우 위험합니다. - `getReader()`를 통해 잠긴 스트림은 반드시 `releaseLock()`을 호출해야 하며, 이를 잊을 경우 스트림이 영구적으로 잠겨 파이프나 취소 등 다른 모든 작업을 수행할 수 없게 됩니다. - 잠금 상태(`locked`)에 대한 정보는 제공되지만, 누가 왜 잠갔는지 혹은 잠금이 유효한지에 대한 구체적인 맥락을 알 수 없어 운영 환경에서의 실수를 유발하기 쉽습니다. **현대적 대안을 통한 비약적인 성능 향상** - 저자가 제시하는 대안적인 접근 방식은 JavaScript 언어 자체의 원시 기능을 활용하며, 기존 Web Streams 대비 모든 런타임(Node.js, Deno, Bun, 브라우저 등)에서 2배에서 최대 120배 빠른 성능을 보입니다. - 이러한 성능 차이는 단순한 최적화의 결과가 아니라, 10년 전의 낡은 설계 결정을 현대적인 JavaScript 패턴에 맞게 근본적으로 다시 설계함으로써 얻어진 결과입니다. 개발자들은 이제 기존 Web Streams의 복잡한 수동 관리 방식에서 벗어나, 현대적인 비동기 반복 기반의 더 직관적이고 효율적인 스트림 API로의 전환을 논의해야 할 시점에 와 있습니다.