개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 함수형 자바스크립트

비동기 동시성 2 — 지연 평가와 Promise 결합

2024년 7월 7일
JavaScriptPromise지연 평가Kleisli Composition

L.map과 L.filter가 Promise를 반환하는 함수를 받았을 때도 올바르게 동작해야 한다. 지연 평가와 비동기가 만나는 지점이다.

L.map + Promise

go와 take가 Promise를 처리할 수 있다면, L.map은 단순히 yield f(a)만 해도 된다.

go(
  [1, 2, 3],
  L.map(a => Promise.resolve(a + 10)),
  take(2),
  log
); // [11, 12]

take가 값을 꺼낼 때 Promise를 만나면 .then으로 기다리고, 이후 작업을 이어간다.

Kleisli Composition — L.filter + nop

L.filter에서는 상황이 다르다. f(a)가 Promise를 반환하면, if (f(a))에서 Promise 자체는 항상 truthy다.

이를 해결하기 위해 nop(no operation) 심볼을 도입했다.

const nop = Symbol('nop');

L.filter = curry(function* (f, iter) {
  for (const a of iter) {
    const b = go1(a, f);
    if (b instanceof Promise) yield b.then(b => b ? a : Promise.reject(nop));
    else if (b) yield a;
  }
});

Promise가 resolve되어 falsy한 값이면 Promise.reject(nop)으로 해당 값을 건너뛴다. take는 nop으로 reject된 Promise를 만나면 그냥 다음 값으로 넘어간다.

go(
  [1, 2, 3, 4, 5, 6],
  L.map(a => Promise.resolve(a * a)),
  L.filter(a => Promise.resolve(a % 2)),
  take(4),
  log
); // [1, 9, 25]

Promise 기반 비동기 필터링이 지연 평가와 함께 동작한다.

← 이전 글비동기 동시성 1 — Promise와 go/pipe 통합
다음 글 →비동기 동시성 3 — async/await와 FxJS map