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

© 2026 newgirok

← 함수형 자바스크립트

비동기 동시성 3 — async/await와 FxJS map

2024년 7월 10일
JavaScriptasync/awaitFxJS동시성

비동기 함수를 go와 pipe 안에서 쓸 때 async/await를 자연스럽게 섞을 수 있다.

async/await with delayIdentity

const delayIdentity = a => new Promise(res => setTimeout(() => res(a), 500));

const f1 = pipe(
  L.range,
  L.map(delayIdentity),
  L.filter(a => a % 2),
  take(3),
  reduce(add)
);

go(f1(5), log); // 1+3 = 4

async/await로 작성해도 결과는 같다.

(async () => {
  const result = await f1(5);
  log(result);
})();

go에 넘긴 f1(5)가 Promise를 반환하고, await로 기다리면 된다. 함수형 파이프라인과 async/await는 충돌하지 않는다.

Array.prototype.map vs FxJS map

Array.prototype.map에 async 함수를 넘기면 Promise 배열이 반환된다.

const result = [1, 2, 3].map(async a => await delayIdentity(a + 10));
log(result); // [Promise, Promise, Promise]

각 값을 꺼내려면 Promise.all이 필요하다.

log(await Promise.all(result)); // [11, 12, 13]

FxJS의 map은 다르다.

go(
  [1, 2, 3],
  map(async a => await delayIdentity(a + 10)),
  log
); // [11, 12, 13]

FxJS map은 내부에서 reduce를 쓰고, reduce는 중간에 Promise가 나오면 .then으로 이어간다. go도 마찬가지로 Promise를 .then으로 처리하기 때문에 log가 받는 값은 이미 해소된 [11, 12, 13]이다. Promise.all을 따로 써야 하는 번거로움이 없다.

동시성 제어가 필요할 때도 차이가 난다.

go(
  [1, 2, 3],
  L.map(async a => await delayIdentity(a + 10)),
  take(2),
  log
);

L.map이면 take(2)가 2개만 요청하고 나머지는 실행하지 않는다. Array.prototype.map은 모든 Promise를 즉시 만들기 때문에 3번 모두 실행된다. 지연 평가와 비동기를 함께 활용할 때는 FxJS 방식이 유리하다.

← 이전 글비동기 동시성 2 — 지연 평가와 Promise 결합