아직 자바스크립트에서 비동기 함수가 어떻게 진행되는지 이해하지 못했다면 [javascript는 어떻게 돌아갈까? 1편] 부터 학습하시면 됩니다.
//다음 코드의 출력 결과는?????
function one(){
console.log('one');
}
function two(){
console.log('two');
}
setTimeout(two,0);
one();
/*
* 정답
* one
* two
*/
어떻게 'one'이 먼저 출력됐을까 ??
//다음 코드의 출력 결과는?????
function one(){
console.log('one');
}
function two(){
console.log('two');
}
function oneSetTimeout(){
console.log('set one');
setTimeout(one,0);
}
function twoSetTimeout(){
console.log('set two');
setTimeout(two,0);
}
setTimeout(oneSetTimeout,0);
setTimeout(twoSetTimeout,0);
/*
* 정답
* set one
* set two
* one
* two
*/
어떻게 이렇게 출력이 됐을까 ??
function one(){
console.log('one');
}
function three(){
console.log('three');
}
setTimeout(one,0);
new Promise((resolve)=>{
resolve('two');
}).then((res)=> console.log(res));
three();
/*
* 정답
* three
* two
* one
*/
어떻게 이렇게 출력이 됐을까 ??
위 예제 뿐만아니라 여러 코드에서 관용적으로 setTimeout(fn, 0)을 사용하는 것을 보셨을 겁니다.
하지만 실제로 setTimeout(fn,0) 의 비동기적 실행 방식이 요긴하게 쓰인다는 것 알고 계신가요 ??
아래의 Ajax를 사용한 코드를 한번 봐보겠습니다.
$('.btn').click(function() {
showWaitingMessage();
longTakingProcess();
hideWaitingMessage();
showResult();
});
위 예제에서 함수들을 간단히 설명하겠습니다.
사용자는 긴 작업 시간이 필요한 longTakingProcess 함수를 기다리는 동안 showWaitingMessage 함수를 통해 '로딩중' 메시지를 보여주고 싶습니다.
하지만 '로딩중' 을 표시하기 위한 이벤트 핸들러는 비동기 적으로 일어나기 때문에 Call Stack안에 있는 longTakingProcess, hideWaitingMessage, showResult 함수가 비어져야 실행될 수 있습니다.
이를 문제를 해결하기 위한 방법으로 setTimeout(fn,0) 을 사용할 수 있습니다.
$('.btn').click(function() {
showWaitingMessage();
setTimeout(function() {
longTakingProcess();
hideWaitingMessage();
showResult();
}, 0);
});
이렇게 실행하게되면, showWaitingMessage가 실행되고, Web API에게 DOM Event를 요청하여 콜백함수를 먼저 Event queue로 보내 '로딩중' 메세지를 보여줄 수 있습니다.
앞으로도 추가적으로 도움이 될만한 예시가 있다면, 가져와서 내용을 추가해보겠습니다 !
Event Loop가 실행되는 방법이 생각보다 까다롭기 때문에 차분히 생각하는 시간과 증명하는 시간이 필요했습니다.
HTML5 Spec [중첩된 타임아웃이 4ms 이하일 경우]을 보면 타임아웃(중첩 5이상)의 최소 지연시간이 4ms라고 나와있습니다. 이것이 중첩 5이상이 아닐 때는 어떻게 적용되는지 한번 더 확인이 필요할 것 같습니다.
이부분도 추후에 정리해서 올려보겠습니다. 😋
덕분에 쉽게 이해하고 가요!