일정 시간이 지난 후에 원하는 함수를 예약 실행(호출)할 수 있게 하는 것을 '호출 스케줄링' 이라고 한다.
호출 스케줄링을 하는 방법은 아래와 같은 방법이 있다.
setTimeout
setInterval
let timeout = setTimeout(function|code, delay, arg1, arg2...);
function|code
delay가 끝나면 실행되는 함수나 문자열
(함수를 실행하지 않고, 함수만 넘겨준다! timer() [X])
문자열(code)은 보안 위험성을 이유로 권장하지 않는다.
delay
앞에 지정된 함수나 코드를 실행하기 전에, 기다려야 할 ms(1000분의 1초) 단위의 시간
arg1, arg2 ... argN
타이머가 만료되고 function에 전달되는 추가적인 매개변수
let timeout = setInterval(function|code, delay, arg1, arg2...);
function|code
delay가 끝나면 실행되는 함수나 문자열
문자열(code)은 보안 위험성을 이유로 권장하지 않는다.
delay
앞에 지정된 함수나 코드를 실행하기 전에, 기다려야 할 ms(1000분의 1초) 단위의 시간
arg1, arg2 ... argN
타이머가 만료되고 function에 전달되는 추가적인 매개변수
setTimeout은 특정 시간 이후 함수가 한번만 실행이 되는데, 재귀 함수를 통해서 주기적으로 반복해서 함수를 호출할 수 있다. 우선 처음 쉽게 생각하면 setTimeout을 사용해서 함수 호출을 반복하기 위해서는 안쪽에서 콜백을 실행시키며 무한 복붙을 해야한다. (아래 예시)
setTimeout(() => {
console.log('2초 지나고 함수 실행');
setTimeout(() => {
console.log('4초 후 함수 실행')
setTimeout(() => {
console.log('6초....');
setTimeout.....
})
})
}, 2000)
이와 같이 무한 복붙을 방지하기 위해, 재귀 함수를 통해서 해결을 할 수 있다.
재귀는 자신을 정의할 때, 자기 자신을 재참조하는 방법을 의미한다. 재귀 함수는 어떤 함수에서 자기 자신을 다시 호출해서 작업을 수행하는 방식의 함수를 의미한다. 재구 함수는 함수 내에서 종료되어야 하는 조건을 반드시 포함시켜야 무한 루프를 방지할 수 있다!
const recursionCall = () => {
setTimeout(() => {
console.log('실행');
recursionCall();
}, 1000)
}
// 실행
recursionCall()
또 다른 예시
let recursionCall = setTimeout(function tick() {
alert('tick')
recursionCall = setTimeout(tick, 2000);
}, 2000)
조건에 따라서 재귀 함수의 delay를 늘려주는 등, 조건을 걸어주기
let delay = 5000;
let recursionCall = setTimeout(function request() {
..어떤 요청 blahblah..
if(서버 과부하, 어떤 이유로 요청이 실패 한다면){
// 다음 실행까지 delay를 늘려주자.
delay *= 2
}
recursionCall = setTimeout(request, delay);
}
}, delay);
함수를 한번 더 묶어서, 재귀 호출을 해보자.
const recursionCall = (callback, interval) => {
const tick = () => {
setTimeout(() => {
callback()
tick()
}, interval)
tick()
}
시간 지연이 있더라도 해당 코드의 동작을 모두 호출시키고 싶은 경우에는 setTimeout 재귀 호출을 사용하고, 중첩되는 경우 무시되더라도 반드시 delay 시간에 해당 코드를 반복하고 싶다면 setInterval 함수를 사용한다.
setTimeout의 실행을 취소하는 식별자로, 함수 내부나 외부에 사용할 수 있다.
let timeout = setTimeout(...)
clearTimeout(timeout)
let timeout = setInterval(...)
clearInterval(timeout)