L.map과 L.filter 등과 같이 평가하는 함수 Promise 대응 필요
take, reduce와 같이 결론 짓는 함수도 Promise 대응 필요
[지연 평가 + Promise - L.map, map, take]
L.map, take Promise 대응
테스트 함수
go(
[Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
L.map(a => a + 10),
take(2),
log);
go(
[Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
map(a => Promise.resolve(a + 10)),
log);
기존 take
export const take = curry((l, iter) => {
const arr = [];
for (const a of iter) {
arr.push(a);
if (arr.length === l) return arr;
}
return arr
}
내가 구현한 Promise 대응 take
export const take = curry((l, iter) => {
const arr = [];
for (const a of iter) {
log(a);
if (a instanceof Promise) {
a.then(res => { // 함수의 실행결과가 즉시 Promise가 되려면 return을 해주어야 한다
if (arr.length < l) {
arr.push(res);
}
});
} else {
arr.push(a);
if (arr.length === l) return arr;
}
}
return arr;
});
개선 1단계
export const take = curry((l, iter) => {
const arr = [];
for (const a of iter) {
if(a instanceof Promise){
return a.then(res => {arr.push(res)
if(arr.length === l) return arr;
// 다시 반복문 시작점으로 가야한다!!
// 이미 return 을 해버려서 take 밖으로 가버렸다
})
}
arr.push(a);
if (arr.length === l) return arr;
}
return arr;
}
개선 2단계 실패작 ( for of 라서 동작하지 않는다!! )
- for of문 같은 경우 중간에 Promise로 끊기면 기다리면서 finally로 가서 해당 이터레이터 중단하고 전부 return 시켜버린다!
For of + Promise 테스트
export const take = curry((l, iter) => {
const arr = [];
return function recur(){
for (const a of iter) {
if(a instanceof Promise) return a.then(a => {
arr.push(a)
return arr.length === l ? arr : recur();
});
arr.push(a);
if (arr.length === l) return arr;
}
return arr;
}()
});
개선 2단계 성공작 while 이용