setTimeout 비동기 함수
setTimeout 타이머 함수는 일정 시간이 경과된 이후 콜백 함수가 호출되도록 타이머를 생성한다. setTimeout 함수가 생성한 타이머가 만료되면 콜백함수가 호출된다.
- 타이머 함수는 ECMAScript 사양에 정의된 빌트인 함수가 아니라 호스트 객체이다.
- setTimeout 함수가 생성한 타이머는 1번 동작하고 콜백함수도 1번 호출된다.
setTimeout 함수
두번째 인수로 전달받은 시간(ms)으로 단 한번 동작하는 타이머를 생성한다. 타이머 만료되면 첫번째 인수로 전달받은 콜백함수가 호출된다.
1 | const timeoutId = setTimeout(func[, delay,param1, param2,...] |
- 콜백함수에 전달할 인수가 있다면 세번째 이후의 인수로 전달할 수 있다.
- setTimeout 함수는 생성된 타이머를 식별할 수 있는 고유한 타이머 id를 반환한다.
- setTimeout 함수가 반환한 타이머 id를 clearTimeout 함수의 인수로 전달하여 타이머를 취소한다.
setTimeout 함수에 대한 오해
흔히들 setTimeout 함수를 인수로 전달해준 딜레이 시간이 지난 후에 콜백함수를 호출해준다고 알고 있다.
하지만 이 말에는 정확히 짚고 넘어가야할 부분이 있다.
setTimeout 함수의 첫번째 인수로 넘겨준 콜백함수는 setTimeout 함수가 호출해주는 것인가?
=> 그렇지 않다.
1 | setTimeout(() => console.log("타이머"), 0); |
만약 위 코드에서 setTimeout 함수가 콜백함수를 호출하는 것이라면 setTimeout 함수의 실행 컨텍스트가 제거되지 않고 남아 있어 “호출해주세요”라는 메시지가 콘솔창에 출력되지 않고 Blocking 현상이 발생해야한다.
하지만 그렇지 않다. 그 이유는 setTimeout 함수는 타이머를 생성하고 timeId를 반환한 후 브라우저에게 타이머 계산과 콜백함수 호출을 위임하고 setTimeout 함수의 실행 컨텍스트가 종료된다.
쉽게 말해서 setTimeout 함수가 브라우저에게 일정 시간이 지나면 콜백함수를 호출해주세요~ 라고 위임하고 종료되는 것이다.
즉, setTimeout 함수의 콜백함수는 브라우저가 호출하는 것이다.
비동기 함수
자바스크립트 엔진의 콜 스택은 싱글 스레드이기 때문에 한번에 한가지 일 밖에 할 수 없다. 그리하여 시간이 오래 걸리는 작업을 하게된다면 그 작업이 끝날 때 까지 다음 코드가 실행되지 못하는 Blocking(블로킹) 현상이 발생한다.
시간이 오래걸리는 작업이나 setTimeout 함수의 콜백함수, addEventListener의 이벤트 핸들러 같은 함수는 개발자가 호출하지 않고 브라우저가 호출한다. 이러한 코드들을 포함하고 있는 함수를 비동기 함수라고 한다.
자바스크립트는 Blocking(블로킹) 현상을 해결하면서 동시성을 추구하기 위해 콜 스택, 태스크 큐, 이벤트 루프 구조를 생성하게 되었다.

위 이미지를 보면서 아까의 코드를 이해해보면,
- 전역 실행 컨텍스트가 생성되어 콜 스택에 쌓인다.
- setTimeout 함수 실행 컨텍스트가 생성되어 콜 스택에 푸시된다.
- setTimeout 함수는 두번째 인수로 전달받은 딜레이를 가진 타이머를 생성하고 브라우저에게 타이머 계산과 첫번째 인수로 전달받은 콜백함수를 호출할 것을 위임하고 timeId를 반환하며 종료되고 실행 컨텍스트 스택에서 pop 되어 종료된다.
- 브라우저는 타이머를 계산하여 만료되면 태스크 큐에 콜백함수를 전달한다. 동시에 콜 스택에서는 console.log 함수 실행 컨텍스트가 생성된다.
- 이벤트 루프는 콜 스택과 태스크 큐를 확인하면서 콜 스택이 비워지면 태스크 큐의 작업을 콜 스택으로 푸시하는 역할을 한다. 즉, console.log 함수 실행 컨텍스트가 제거되고 전역 실행 컨텍스트가 제거되기 전까지는 태스크 큐에 있는 콜백함수가 콜 스택으로 푸시될 수 없다.
- console.log 함수가 종료되어 실행 컨텍스트가 pop되어 제거되고 전역 실행 컨텍스트도 pop되어 제거되면 이벤트 루프가 콜 스택이 비어있는 것을 확인하여 태스크 큐의 콜백함수를 콜 스택으로 푸시한다.
- 브라우저가 호출하여 콜백함수의 실행 컨텍스트가 생성되고 콜백함수를 실행한 뒤 종료되면 실행 컨텍스트 스택에서 pop되어 제거되고 코드가 종료된다.
7번에서 브라우저가 콜백함수를 호출한다는 의미는 태스크 큐에 있던 콜백함수를 콜 스택으로 이동시켜준다는 의미이다.
다음 시간에는 비동기 함수의 callback 패턴과 promise 패턴, async, await에 대해서 알아보자.