작성
·
222
0
복습을 하고있던 중에 이런 코드를 돌리면서 생각을 했는데요.
[...iter]를 실행하는 과정에서 예를들어 여기에서 3이 내려온다고 생각해봤습니다.
map1의 f1가 적용된 f1(3)이 될 것이고 이 f1(3)이 filter에 적용되려면 아래로 내려가야됩니다.
go는 reduce로 구현되어있고 reduce에 의해 꺼내진 cur이 f1(3)이 될것이고 얘는 promise 입니다.
filter2의 f2에 적용되기 위해서 f1(3)은 reduceF에 들어갈 것인데요
reduceF엔 보시다시피 catch가 달려있습니다.
따라서 여기까지 내려온 3은 f1(3).then(f2).catch() 이렇게 되있을것이고
따라서 마지막 map3을 거쳐서 [...iter]에 프로미스가 내려왔을때,
3이 들어간 프로미스의 모습은 f1(3).then(f2).catch().then(f3).catch()
이렇게 되어있을거라고 생각합니다. 그럼 각 프로미스에 catch가 달려있으니 nop에 대한 에러처리가 필요없을 것이라고 생각했습니다.
그런데 실행시켜보면 에러가 콘솔에 찍힙니다.
그렇다는건 실제로는 reduceF를 거치지않고 then으로만 내려왔다는 것일까요?
아무리 생각해봐도 이해가 되지 않네요..
답변 3
0
0
이해했습니다. L.map, L.filter 가 제네레이터가 바로 takeAll 처럼 바로 배열을 생성하는 것도 아니고 go에 선언된 함수에선 제네레이터 상태로 넘겨지고 reduceF 에 들어갈일 없이 [...iter] 에 의해 풀려서 f(g(h))) reduceF에 의한 처리 없이 단순하게 map, filter, map 안의 함수합성으로 next()가 끝날때까지 뱉어버리고 마네요.
마지막 행이 catchnoop 없는 C.reduce라도 reduceF가 있는데 에러가 찍히는 이유는 reduceF를 포함하는 recur로 재귀를 도는데 [...iter] 배열 요소가 같은 시간이 걸리는 프로미스라고 가정하면 첫번째 이외의 배열요소는 그 요소를 처리할 reduceF의 recur이 태스크 큐에서 순차적으로 돌고있는데 그 배열요소는 recur보다 먼저 reject로 resolved되버려서 콘솔에 에러가 찍힐수 밖에 없었던 거네요.
사실 이런거보다 더 중요한건 고차함수를 어떻게 잘 만들어내서 활용하는지인데 이런 과정이 납득이 안되면 뭘해도 답답한 느낌이 들어서 계속 묻게되네요. 답변 감사합니다.
0
글로 설명을 모두 드리기 조금 어렵지만 마지막 L.map을 그냥 map 으로 해보시면 원하시는 결과를 얻으실 수 있습니다.
그런 이유는 L.map 이후에 takeAll 을 하는 것이 map 이기 때문입니다.
takeAll 에서 실제로 실제로 nop이 제거되고 배열 내 하나의 값들 마다 promise의 효과를 제어하기 때문입니다.
감사합니다.