작성
·
903
0
const reduce = curry((f, acc, iter) => {
if (!iter) {
iter = acc[Symbol.iterator]();
acc = iter.next().value;
} else {
iter = iter[Symbol.iterator]();
}
return (function recur(acc) {
let cur;
while (!(cur = iter.next()).done) {
const a = cur.value;
acc = f(acc, a);
if (acc instanceof Promise) acc.then(recur);
}
return acc;
})(acc);
});
const go = (...args) => reduce((a, f) => f(a), args);
go(
1,
(n) => Promise.resolve(n + 10),
(n) => n + 100,
log
);
위와 같이 acc.then을 리턴하지 않는 경우 log에 값이 깨져 보여서 설연휴 동안 계속 왜이런지 고민해서 내린 답인데 글이 길지만 한번 제가 내린답이 맞는지 틀렸다면 어디부분이 잘못됐는지 확인좀 부탁드립니다...! 길어서 댓글로 남기겠습니다.
답변 3
1
1
이후 return을 함으로써 recur 함수가 종료됨 **즉 콜스택이 비워져 있는 상태이며 이터레이터의 값이 모두 소비되지 않은 상태
이벤트 루프에 의해 콜스택이 비워져 있기 때문에 태스크큐에 있는 콜백 함수로 전달된 recur함수가 콜스택으로 옮겨져 실행됨
이때 then메서드로 전달된 콜백 함수의 인자 값은 resolve된 값 11이며 이 값이 recur함수 인자로 전달되며 재귀적으로 실행되면서 남아있는 이터레이터의 값을 소비
이후 while문을 루핑하며 결과값을 차례대로 합성하여 log에 출력
1
* 편의를 위해 (n) => Promise.resolve(n + 10)함수는 a1 (n) => n + 100함수는 a2라고 칭하겠습니다.
acc = f(acc ,a)에 의해 a1 함수의 호출로 Promise의 resolve함수가 호출되어 fulfilled상태(Promise {<fulfilled>: 11})의 프로미스 값이 acc에 담김
acc는 Promise의 인스턴스 이므로 콜백으로 recur함수를 전달하는 acc.then함수 호출
이때 acc.then메서드가 호출 되면서 콜백함수를 태스크큐에 전달
이후 return이 없으므로 동기적으로 while문 루핑
루프에 의해 a2(acc) === a2(Promise {<fulfilled>: 11}) 이기 때문에 a2함수 호출 결과값이 acc에 의도하지 않은 값([object Promise]100)이 담김;
이터레이터의 마지막 요소인 log(acc) 즉 log([object Promise]100) 호출 되어 출력
이후 태스크큐 -> 콜스택 으로 옮겨진 콜백함수가 실행되는 시점에는 상위스코프의 이터레이터의 값이 모두 소비 된 상태이기 때문에 while문을 실행하지 않고 recur함수 종료
네 맞아보입니다 :)