오늘 강의 중에 튜터님께서 질문하신 것중
"setTimeout과 setInterval을 같이 사용할 경우 어떤 현상이 발생할까?"
라는 질문에 답이 생각이 나지 않아 setTimeout과 setInterval에 대해 다시 공부하고 동시에 사용했을때의 현상을 알아보았다.
setTimeout은 콜백함수와 delay(지연시간)을 인자로 받아 지연시간이 지난 후 콜백함수를 실행시키는 함수이다.
내가 setTimeout에 대해 원래 알고 있는 것은 다음과 같다.
setTimeout(() => console.log("world"), 0);
console.log("hellow");
위와 같은 코드에서 setTimeout의 delay가 0이기에 world가 먼저 출력된 후 hellow라는 결과가 출력될 것 같지만 실제 결과는 다음과 같다.
위와 같은 결과가 발생하는 이유는 setTimeout의 특징 중 하나인데, setTimeout은 현재 실행하고 있는 스크립트가 종료되고 난 후 지연시간이 지나고 콜백함수를 실행시킨다.
let count = 0;
setTimeout(function log() {
console.log(count++);
setTimeout(log, 500);
}, 500);
위의 코드는 setTimeout 내부에 setTimeout(log, 500)을 넣어 setInterval과 같이 주기적으로 log를 실행하는 함수이다.
결과는 다음과 같다.
위의 결과와 같이 setTimeout을 중첩시키면 setInterval과 같이 사용할 수 있다.
setTimeout은 콜백함수와 delay(지연시간)을 인자로 받아 지연시간이 지날때마다 콜백함수를 실행시키는 함수이다.
let before = new Date().getTime();
setInterval(() => {
const now = new Date().getTime();
console.log(now - before, "만큼 지남");
console.log("setInterval이지롱");
}, 2000);
setTimeout(() => {
const now = new Date().getTime();
console.log(now - before, "만큼 지남");
console.log("setTimeout이지롱");
for (let i=0; i<10000000000; i++) {}
}, 1500);
위의 코드를 실행시키면 setInterval과 setTimeout안의 콜백함수가 몇초 후 실행되는지를 출력해준다. 또한 setTimeout의 콜백함수는 반복문으로 인해 소요 시간이 굉장히 길다.
결과는 다음과 같다.
분명 setTimeout은 1.5초 후에, setInterval은 2초마다 실행되어야 하지만 setTimeout은 정상적으로 실행된 반면에 setInterval은 9초가 지난후에야 실행된다.
그 이유는 다음과 같은 두가지 특성때문이다.
즉, 싱글스레드에서 동기적으로 실행을 한다면 현재 진행중인 작업이 오래걸릴 경우 후에 일어나는 작업은 미뤄지고 멈춘 것처럼 보이며, 사용자 입장에서는 작동하지 않는 것처럼 보일 수 있다.
즉 위의 코드에서는 setTimeout이 setInterval 보다 먼저 실행되는데 setTimeout이 약 7~8초 정도 소요시간이 걸리기 때문에 setInterval은 그때까지 실행이 미뤄진다.