작성
·
326
0
안녕하세요.
먼저 좋은 강의와 항상 빠르게 답변을 해주셔서 너무 감사합니다.
질문은 아래와 같습니다.
지연성 1 파트에 있는 평가순서
강의를 복습하면서 클레이슬리 컴포지션의 평가 순서를 생각해보았는데, 제 생각이 맞는지 궁금합니다.
예시코드
// go
go(
[1, 2, 3, 4, 5],
L.map((n) => Promise.resolve(n)),
L.filter((n) => n % 2),
take(2),
console.log // [1, 3]
);
// take
export const take = curry((l, iter) => {
let result = [];
iter = iter[Symbol.iterator]();
// recur()가 실행되면, 여기서 다시 시작을 하는데.
// iter.next()가 실행되면,
return (function recur() {
let cur;
while (!(cur = iter.next()).done) {
const value = cur.value;
// a가 promise 인 경우 재귀함수를 이용해서 처리함
if (value instanceof Promise)
return (
value
//
.then((v) =>
(result.push(v), result).length === l ? result : recur()
)
// filter에서 reject가 되면, catch에 걸리고 e가 nop이면 recur()를 실행한다.
.catch((e) => (e === nop ? recur() : Promise.reject(e)))
);
result.push(value);
if (result.length === l) return result;
}
return result;
})();
});
// L.filter
const nop = Symbol("nop");
export const 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;
}
});
// L.map
export const L.Map = curry(function* (f, iter) {
for (const el of iter) {
yield go1(el, f);
}
});
take
함수 내, iter.next()
평가를 시도 → L.filter로 이동
L.filter
내, iter.next() 평가를 시도 → L.map 으로 이동
L.map
내, inter.next() 평가를 시도한다. → [1, 2, 3..] 를 iter 로 받았기 때문에 1로 평가 된다.
L.filter
로 돌아와, L.map으로부터 평가받은 Promise.resolve(1)
이라는 값(b)으로 내부 로직을 수행한다.
b의 인스턴스가 Promise라면, b.then을 실행하고 a
또는 Promise.reject
을 한다.
여기서 a는 Promise 이다.
b의 인스턴스가 Promise가 아니라면, result.push(value);
을 실행하고 while로 순회한다.
L.filter 의 평가가 끝나면 take
함수로 돌아온다
take로 전해지는 L.filter 의 평가값은 4개 중에 하나일 것이다.
a
→ take 내에서 result.push 가 실행됨
Promise.resolve(a)
→ take 내에서 .then 절
이 실행됨.
Promise.reject(nop)
→ take 내에서 .catch 절
이 실행되고 recur()
를 실행함
Promise.reject(e)
→ take 내에서 .catch절
이 실행되고, Promise.reject(e)
로 이어짐
recur()
가 실행되면, take
에서 실행된 첫번째 while 사이클이 끝나면서, 다시 recur()가 실행되며 iter.next()
가 평가할때 위 과정을 다시 반복한다. take에 있는 while 사이클이 return되고 recur()
함수 실행이 종료됐음에도 iter.next()
의 값이 이전값에서 이어지는 이유는 recur()
와 iter가 클로저이기때문이다.
엄청 디테일하게 잘 보셨네요!