[JavaScript] setTimeout(callback, 0)을 사용하는 이유

setTimeout에 시간을 0을 줘서 사용하는 경우가 있다.

이렇게 하면 아래와 같은 경우에 setTimeout을 적용한 3이 가장 마지막에 찍히는 것을 확인할 수 있다.

 

console.log(1);
console.log(2);
setTimeout(()=> console.log(3), 0);
console.log(4);
console.log(5);

// 1, 2, 4, 5, 3

 

setTimeout(callback, 0)을 사용하는 이유에 대해 공부하다가 좋은 블로그 글을 보아서 배운 내용을 가볍게 정리하고 블로그 주소를 남겨놓고자 한다.

 

setTimeout에 시간을 0초로 주는데도 뒤늦게 실행되는 이유는 정리하자면 이런 식이다.

 

어떤 함수를 실행시킬때 발생하는 실행 컨텍스트는 자바스크립트 엔진의 콜스택에 들어가 실행되는데(자바스크립트 엔진은 콜스택과 메모리 힙으로 이루어져있음), setTimeout, setInterval과 같은 비동기 함수의 콜백함수와 이벤트 핸들러는 자바스크립트 엔진을 감싸는 브라우저, 혹은 Node.js 환경의 태스크 큐에 임시 보관된다. 그리고 콜스택과 태스크큐의 상태를 번갈아 확인하는것이 이벤트 루프이다. 

 

위 예시의 경우에서 콜스택에는 console.log(1), console.log(2)가 순차적으로 들어왔다가 실행되어 나가기를 반복한다. 그리고 세 번째로 setTimeout이 콜스택에 들어오고, 브라우저에서 타이머를 실행시킨 후 pop 되어 나간다. 타이머는 0으로 설정했지만 크롬 환경에서는0.4ms이하의 경우엔 0.4ms 를 할당하므로 브라우저에서는 0.4ms의 타이머가 실행되고, 그 사이에 빈 콜스택에는 console.log 4와 5가 순차적으로 들어왔다가 나간다. 0.4ms 후에 브라우저는 setTimeout의 콜백함수인 console.log(3)을 태스크큐에 할당한다. 이벤트 루프는 콜스택과 태스크큐를 계속 감시하다가, 비어있는 콜스택에 태스크큐에 들어있던 console.log(3)을 집어넣는다. 

 

이러한 방법은 무거운 함수를 지연시키거나, 어떤 함수를 강제로 지연시켜 순차적으로 실행시킬 때 활용할 수 있다. 

 

아래 블로그 글을 통하여 setTimeout(callback, 0)과 콜스택, 테스크큐, 이벤트루프까지 양질의 공부를 할 수 있었기에 꼭 읽어보길 바란다.

https://velog.io/@edie_ko/javascript-eventloop

 

setTimeout(foo, 0)에서 foo는 정말 0ms 후에 실행될까?

자바스크립트의 비동기 처리와 이벤트루프, 마이크로태스크 큐에 대해 설명합니다.

velog.io