<aside> 💡 앞에서 구현했던 L.map과 take를 사용해서 아래와 같은 코드가 있다고 하자
</aside>
go(
[1, 2, 3],
L.map((a) => a + 10),
take(2),
log
) // [11, 12]
<aside> 💡 Promise가 초기값으로 진행되면 어떻게 될까?
</aside>
go(
[Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
L.map((a) => a + 10),
take(2),
log
) // ['[object Promise]10', '[object Promise]10']
<aside> 💡 L.map에 대해서 promise를 판단해서 풀어주는 코드가 필요하다! go1을 이용해서 L.map 함수를 수정해주자
</aside>
const go1 = (a, f) => (a instanceof Promise ? a.then(f) : f(a))
const L = {}
L.map = curry(function* (f, iter) {
for (const a of iter) {
yield go1(a, f)
}
})
<aside> 💡 아직은 promise값을 그대로 출력하고 있다 .then()으로 적용해서 take에 넘겨주어도 그 값은 promise에 담겨서 전달되기 때문에! take 함수에서도 promise를 받으면 상태값을 얻을수 있도록 수정해보자 !!
(아래와 같이 take 함수의 while문 안의 cur.value를 확인해보면 .then()을 통해서 처리된 값이 promise에 담겨서 넘어온 것을 확인할 수 있다)
</aside>
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((el) => { // ...(1)
res.push(el)
if (res.length == l) return res
return recur() // ...(2)
})
}
res.push(a)
if (res.length == l) return res
}
return res
})()
})
<aside> 💡 take에서 promise를 풀어가는 과정에서 (1)은 이미 if문 안에서 return이 들어갔기 때문에 promise를 검토하고 res 배열의 길이가 변수 l 보다 작다면 다시 while문을 돌아야 하는데 (1)에서 return이 되면서 끝나기 때문에 재귀를 이용해서 유명함수를 만들고 (2)와 같이 구현해줘야 한다!
</aside>
<aside> 💡 take 함수의 코드를 조금 더 간결하게 정리해보자
</aside>
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((el) => {
res.push(el)
return res.length == l ? res : recur() // 3항!
})
}
res.push(a)
if (res.length == l) return res
}
return res
})()
})
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((el) => {
// (res.push(el), res)로 변경해서 res에 대한 push와
// push된 res를 바로 확인할 수 있도록 코딩해준다
return (res.push(el), res).length == l ? res : recur() // 변화를 준 부분
})
}
res.push(a)
if (res.length == l) return res
}
return res
})()
})
<aside> 💡 이제 아래와 같이 promise를 L.map의 변수 및 take가 받는 변수에 적용해도 원하는 값을 받을수 있게 된다!
</aside>
go(
[Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
L.map((a) => Promise.resolve(a + 10)),
take(2),
log
) // [11, 12]