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

© 2026 newgirok

← 함수형 자바스크립트

비동기 동시성 1 — Promise와 go/pipe 통합

2024년 7월 5일
JavaScriptPromise비동기함수형 프로그래밍

기존 콜백 방식은 중첩이 깊어질수록 읽기 어렵다.

add10(5, res => {
  add10(res, res => {
    add10(res, res => {
      log(res);
    });
  });
});

Promise의 .then 체이닝은 이걸 평탄하게 만들지만, 함수형 파이프라인(go, pipe)과 섞어 쓰기 위해서는 추가 작업이 필요하다.

Promise는 일급이다

Promise도 변수에 담거나 인자로 넘기거나 반환할 수 있다. 이 점을 활용해서 go1을 만들었다.

const go1 = (a, f) => a instanceof Promise ? a.then(f) : f(a);

인자가 Promise면 .then으로 연결하고, 아니면 즉시 실행한다.

go에서 Promise 처리

go는 내부적으로 reduce를 쓰는데, reduce가 Promise를 받으면 .then으로 연결하도록 수정했다.

const reduce = curry((f, acc, iter) => {
  // ...
  return go1(acc, function recur(acc) {
    let cur;
    while (!(cur = iter.next()).done) {
      const a = cur.value;
      acc = f(acc, a);
      if (acc instanceof Promise) return acc.then(recur);
    }
    return acc;
  });
});

이제 go 안에서 Promise를 반환하는 함수가 있어도 자연스럽게 동작한다.

go(
  Promise.resolve(1),
  a => a + 10,
  a => Promise.resolve(a + 100),
  log
); // 111

중간에 Promise.reject가 발생하면 이후 함수들을 건너뛰고 .catch로 전달된다.

go(
  Promise.resolve(1),
  a => a + 10,
  a => Promise.reject('error'),
  a => a + 1000, // 실행 안 됨
  log
).catch(e => log(e)); // 'error'

함수형 파이프라인 안에서 비동기 에러 처리도 선언적으로 된다.

← 이전 글지연 평가 — L.range, L.map, L.filter
다음 글 →비동기 동시성 2 — 지연 평가와 Promise 결합