이 강좌에 대한 질문은 아닌데 질문이 있습니다.
232
작성한 질문수 10
선생님의 함수형 프로그래밍 책을 사서 혼자 학습하고 인프런 함수형프로그래밍 무료강의를 막 다듣고 책 복습하고 있는 학생인데요.
함수형 프로그래밍 책의 2장의 비동기와 재귀부분의 코드를 읽는데
설명이 간략하게만 나와있어서 질문드립니다.
function _async(func) {
return function() {
arguments[arguments.length++] = function(result) {
_callback(result);
};
// 변경된 부분
(function wait(args) {
/* 새로운 공간 추가 */
for (var i = 0; i < args.length; i++)
if (args[i] && args[i].name == '_async_cb_receiver')
return args[i](function(arg) { args[i] = arg;
// func.apply(null, args);
wait(args);
});
func.apply(null, args);
})(arguments);
var _callback;
function _async_cb_receiver(callback) {
_callback = callback;
}
return _async_cb_receiver;
};
}
log(div(sub(add(10, 15), 5), 10));
이 코드에서요. wait()이 하는 역할이 잘 이해가 되지않습니다.
제가 이해한 바로는
log->div->sub->add순으로 call stack에 쌓이고
add실행 시, async를 받고 wait(args) 실행할때는 _async_cb_receiver가 없기 때문에 그냥 반복문만 돌고 func.apply()되고
그다음 sub가 실행되는데 add가 async_cb_receiver를 리턴하여 첫번째 인자 args[0]에 걸려서
return add의 _async_cb_receiver(function(arg) { args[i] = arg; wait(args)}); 를 실행합니다.
여기서, _ async_cb_receiver함수는 _callback 변수에 인자로 들어간 익명함수를 할당하고 다시 _async_cb_receiver를 리턴합니다.
마찬가지로 이것이 반복되어 log까지 실행되고,
백그라운드에는 add, sub, div, log의 setTimeout이 시간을 세다가 task queue로 돌아와서 main이 종료되고 wait과 args를 참조하는 클로저인 콜백함수들이 이벤트 루프에 의해 하나씩 실행되는데
먼저 add의 콜백함수가 실행될 때는 _async_cb_receiver가 안걸려서 그냥 넘어갈 것이고,
그다음으로 sub의 콜백함수가 실행될 때, 아까 할당해놓았던 _async_cb_receiver가 걸려서 익명함수 function(arg) { args[i] = arg; wait(args)}가 result를 받아서 실행될텐데 책의 해설에서는 값을 치환하면서 재귀한다고 하셨는데요. args는 이 async_cb_receiver의 인자인 이 익명함수와 wait의 클로저가 참조하고 있는 sub의 args일 것이고 args[0]에 add의 리턴인 async_cb_receiver가 걸려서 _callback이 받은 result로 args[0]에 result를 할당하여 치환했고 다시 wait을 다시 실행하는데요.
왜 wait이 다시 재귀로 도는지 아무리 생각해도 이해가 안갑니다.
저 코드에서 wait(arg) 부분을 주석처리하고 익명함수에 func.apply(null, args)를 넣어도 에러없이 돌아갔는데요. sub가 _async_cb_receiver를 만났을때 값만 치환하고 func.apply()를 하면 됐지 다시 wait을 켜서 for문을 돌며 _async_cb_receiver를 확인하면서 기다려야되는 이유가 있나요?
질문이 두서없어서 죄송합니다. 저도 머릿속으로 최대한 상황들을 그려내려고하는데 지식이 부족해서 뭐가 어떻게 돌아가는지 정확히 모르겠네요..
혹시 비동기 상황에서 log, sub, div, add의 콜백들이 어떤순서로 실행되는지는 알수 없기때문에 wait()을 쓰며 결과를 받을때까지 계속 자기자신으로 재귀하는건가요?
더 생각해보다가 다시 궁금한 점이 생겼는데 wait함수를 실행할때마다 콘솔에 찍히게
(function wait(args) {
console.log(args[0] + args[1] + " wait");
/* 새로운 공간 추가 */
for (var i = 0; i < args.length; i++)
if (args[i] && args[i].name == '_async_cb_receiver')
return args[i](function(arg) { args[i] = arg;
wait(args);
});
func.apply(null, args);
})(arguments);
이런식으로 찍어봤는데요. 저는 wait()이 마구 재귀할줄알았는데 실행결과를 보니 사이사이에 한번씩만 찍혔습니다.
콜백함수에서 wait() 재귀함수를 호출할경우 바로 실행되서 결과받을때까지 도는게 아니라 콜백함수처럼 다시 백그라운드 갔다가 task queue로 가서 콜백함수처럼 실행되나요?
정확한 동작을 알고싶은데 제 검색능력이 딸려서 잘 못찾겠네요
답변 1
2
안녕하세요. 답변이 좀 늦었습니다. 요즘 제가 프로젝트 막바지여서 조금 바쁘네요.
인자에 콜백이 필요한 값이 없을 때까지 치환하고서 func.apply를 실행하도록 하는 코드입니다. 단순히 재귀를 사용하는 패턴을 보여드리는 것이니, Promise와 async/await를 더 깊이 들여다 보고 있는 본 영상 강의의 비동기 프로그래밍 스타일을 연습해보시는 것이 더 좋을거 같습니다. :)
프론트엔드 실무에서 어떤때에 쓰이는지 궁금합니다
1
111
1
함수형 프로그래밍 심화 강의 자료 추천
0
72
2
함수형 자바스크립트 프로그래밍 책
0
54
1
filter가 아무것도 걸러내지 못하는 경우
0
114
1
take 함수의 성능적면에서의 이점
1
463
1
pipe함수
1
531
1
Identity 함수
0
451
1
함수형 프로그래밍이란
0
832
1
reduce 예제 코드 제안!
0
405
1
fxts를 배워보려고 합니다.
1
537
1
flatMap 관련 질문드립니다~
1
444
1
다용성이 높은 L.flatMap
0
358
1
변수에 재 할당 금지~
0
540
1
DevTools라고 옆에 결과 확인하는거 어떻게 하나요?
0
483
2
소요시간에 관해서 질문드립니다
1
458
1
join에 대한 내용이 궁금증이 해결되지 않아서 질문드립니다!
0
465
2
reduce에 L.range를 사용할 때
0
527
2
[이해내용 공유] Lazy 에서 C.reduce가 병렬 효과를 내는 이유
3
739
2
제가 이해한 C.Reduce와 Reduce의 동작 차이 정리
2
787
3
go, pipe 함수 관련하여 질문 드립니다.
1
499
1
안녕하세요 강사님!
0
380
2
fxts에 go가 없는 이유?
0
840
1
비동기 관련 질문입니다!
0
462
1
질문 있습니다.
0
517
1





