take 비동기 제어

nn·2023년 6월 27일
0
go([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
  L.map(a => a + 10),
  take(2),
  log)

위 코드를 실행하면 다음과 같이 promise가 나온다.

L.map에서 go1함수를 통해 promise인 경우를 처리하여 11, 12가 나왔지만, L.map에서 리턴한 프로미스를 take에서 처리하지 못했기 때문이다.

   const take = curry((l, iter) => {
        let res = [];
        for (const a of iter) {
          res.push(a);
          if (res.length === l) {
            return res;
          }
        }
        return res;
      });

take는 이렇게 되어있다.
여기서 프로미스를 제어해보자.

현재 iter에는 위의 콘솔처럼 프로미스 배열이 들어가 있다.
반복문에서 promise인 경우를 처리해주면 된다.

  const take = curry((l, iter) => {
    let res = [];
    iter = iter[Symbol.iterator]();
    return (function recur() {
      let cur;
      while (!(cur = iter.next()).done) {
        const a = cur.value;
        if (a instanceof Promise) {
          return a.then(a => {
            res.push(a);
            if (res.length === l) return res;
            return recur();
          })
        }
        res.push(a);
        if (res.length === l) return res;
      }
      return res;
    })();
  })

recur()라는 유명함수를 만들고 즉시 실행하게 해 두었다.

a가 프로미스인 경우 프로미스를 풀고, res에 담게 된다.
res의 길이를 확인하고, 값을 더 담아야한다면 다시 recur()를 실행한다.

위 코드를 적용하면 위와같이 정상적으로 실행된다.

profile
내가 될 거라고 했잖아

0개의 댓글