타이머를 이용한 지연 실행과 반복 실행
타이머 함수는 이미지 슬라이드, 시계, 타이머, 반응 대기, 로그인 유지를 위한 시그널 전송, 일정 주기의 화면 갱신 등 일정 시간 후에 실행하거나, 반복적으로 자동 재실행하는 웹 기능을 구현하는데 사용합니다.
자바스크립트는 이런 기능을 이한 전역 함수 2개를 제공합니다.
setTimeout() 은 지연 시간 후 1번 콜백 함수를 실행하고 종료하며, setInterval() 은 지연 시간 간격으로 콜백 함수를 무한 반복 실행합니다.
setTimeout(callback, 지연시간(ms));
setInterval(callback, 지연시간(ms));
callback : 설정한 시간후 실행하는 함수입니다. 타이머 함수안에 직접 구현해도 되고, 별도의 함수를 정의해 이름으로 콜백 함수를 지정할 수 있습니다.
지연시간 : 밀리세컨드 단위입니다. 1000 은 1초입니다.
예를 들어
setTimeout(function(){ console.log('타이머 실행!');}, 3000);
이 타이머는 3초후에 콘솔에 메시지를 실행합니다.
!주의할 점
타이머 함수라는 용어를 사용하지만, 정확하게는 웹브라우저의 전역 윈도우(window) 객체의 메서드입니다.
setTimeout() 은 window.setTimeout() 을 줄여서 사용하는 것입니다. 자바스크립트 전역 객체의 메서드 사용시 "window." 은 생략이 가능하며, 또 실제로 대부분 그렇게 사용합니다.
우리가 전역 함수라고 부르는 또는 별도의 객체명 없이 함수명만으로 사용하는 것들은 모두 윈도우(window) 전역 객체의 메서드(Method)입니다.
지연 실행(setTimeout)
일정 시간 후 콜백 함수를 실행합니다.
콜백 함수 안에 다시 타이머를 넣어 타이머를 중첩 실행할 수 있습니다.
타이머를 해제하려면 타이머 객체 참조가 반드시 있어야 하며, clearTimeout() 메서드로 지연 실행을 해제할 수 있습니다.
따라서, 지연 실행 타이머 설정시 반환되는 타이머 객체 참조를 변수에 저장해 보관해두어야 합니다.
지연 실행 타이머를 중첩 실행 할 경우, 타이머 객체의 참조를 관리하지 못해 메모리 누수가 발생할 수 있으므로, 중첩 실행시에는 타이머 객체 관리에 주의해야 합니다.
지연 실행 타이버를 활용하면 반복 실행 타이머와 같은 기능을 하도록 구현 할 수 있습니다.
반복 실행하는 지연 실행 타이머는(setTimeout) 반복 실행 타이머(setInterval)로 대체가 되지만, 실행 시점에 지연 시간이 가변으로 변하는 경우 지연 실행 타이머를 활용할 수 있습니다.
예를 들어 보겠습니다.
let delay= 1000;let timer = setTimeout(callbackFunc, delay);
function callbackFunc(){ //지연된 기능 실행 코드 console.log((delay/1000).toString()+'초 후 지연 실행!') delay *= 2; //이전 실행 시간의 2배 timer = setTimeout(callbackFunc, delay); //지연 실행 설정}
이렇게 구현한 지연 실행 타이머는 이전 지연 시간의 2배씩 늘어나면서 계속 자기 자신(콜백 함수)을 반복 호출합니다.
만들기에 따라서는 다양한 알람 기능에 활용할 수 있습니다.
조금 더 세련되게 객체 리터럴을 사용해서 지연 실행되는 알람 메시지를 표시하는 객체를 만들어보면 아래와 같이 구현할 수 있습니다.
let alarm = { notice: function(delay){ this.clear(); this.timer = setTimeout(this.msg, delay*1000);
}, clear: function(){ if(this.timer){ clearTimeout(this.timer); this.timer = undefined; } }, msg: function(){ console.log('alarm!'); }}alarm.notice(3);
반복 실행
일정 시간 주기로 반복 실행하는 기능을 구현할 수 있습니다.
서버에서 일정 시간 주기로 데이터를 가져와 화면에 데이터를 갱신하거나, 로그인 유지를 위해 서버에 주기적으로 시그널을 보내는 용도로 사용할 수 있습니다.
반복 실행 타이버는 해제하지 않으면 계속 실행되며, 콜백 함수에서 에러가 발생할 경우
let timer = setInterval(callbackFunc, 1000);let timer2 = setInterval(function(){ //콜백 실행 코드}, 1000);
와 같이 사용합니다.
기본적인 setTimeout() 와 동일하며, 시간 간격으로 반복실행되는 차이만 있습니다.
지연 실행과 반복 실행의 정지
지연 실행으로 지연되고 있는 중 이거나, 반복 실행 중인 타이머 객체를 없애주면 지연된 콜백 함수는 해제됩니다.
콜백 함수 해제를 위해서는 실행한 지연 실행, 또는 반복 실행 타이머 객체의 참조를 알아야 합니다.
따라서 지연 실행, 또는 반복 실행을 할 때는 타이머 함수 실행 후 반환되는 객체 참조를 변수에 담아두어야 합니다.
예를 들어
const timer = setTimeout(callbackFunc, 10000);
이렇게 지연 실행 타이머 객체를 변수에 담아두었다가, 중간에 지연 실행 타이머가 필요 없어진 경우
clearTimeout(timer);
이렇게 타이머 객체를 인자로 해서 clearTimeout() 전역 함수를 실행하면 타이머 객체가 해제 됩니다.
타이머 객체를 해제한 후에는 참조 변수에 undefined 를 적용해 객체가 해제된 것을 표시하는 것을 추천합니다.
타이머 참조 변수가 undefined 인지 여부로 타이머 객체가 해제되었는지를 조건절 체크로 확인할 수 있기 때문에 타이머 관리를 할 때 편리합니다.
반복 실행 순서의 유지
여러 개의 반복 실행하는 콜백 함수를 작성해서 일정 시간 간격으로 실행하는 경우, 당연히 순서대로 계속 반복해서 실행이 될 거라고 예상을 합니다.
그러나 자바스크립트는 같은 시간 주기로 순서대로 실행했다고 해서, 다음번에도 같은 시간 지연 후 같은 순서대로 실행될 것이라는걸 보장하지 않습니다.
다음번 실행 시간이라는 것은 콜백 함수 실행이 끝난 후, 지연 시간만큼 타이머가 다시 도는 것입니다.
콜백 함수의 실행 시간이 길 경우 먼저 실행된 콜백 함수가 더 늦게 반복 실행 대기에 들어갈 수 있습니다.
결국 뒤에 실행된 콜백 함수가 다음번에는 먼저 실행될 수 있습니다.
원격 서버에서 AJAX로 데이터를 받아와 처리를 하는 경우 원격 서버의 지연 등으로 인해 긴 시간 서버의 응답을 대기하게 되는 경우, 이런 현상이 빈번하게 발생합니다.
코드 위치상 앞선 콜백 함수의 결과를 기준으로 나중에 실행하는 콜백 함수의 실행 조건을 변경하는 것은 처음 한번만 실행 순서가 유지될 뿐, 그 다음부터는 실행 순서를 보장할 수 없습니다.
따라서 주기적으로 실행하는 콜백 함수간의 실행 순서가 바뀔 수 있다는 점을 항상 염두해두고 상호 의존하지 않는 코드를 작성해야 합니다.