호출 스케줄링 구현 setInterval & setTimeout

JY·2021년 3월 31일
1

호출 스케줄링(scheduling a call)이란?

일정 시간이 지난 후에 원하는 함수를 예약 실행(호출)할 수 있게 하는 것

  • setInterval() - 일정 간격을 두고 반복 실행
  • setTimeout() - 일정 시간 후 한번 실행



1. setInterval - 반복 실행

일정 시간 간격을 두고 함수를 반복해서 실행

1) 문법

  • 1000millisecond = 1초
setInterval(실행할함수, 시간간격ms(기본값=0), [인수1, 인수2...])

2) 예제

  • case 1 - 함수 전달
function sayHi() {
  alert('안녕하세요.');
}

setInterval(sayHi, 1000); // sayHi()처럼 함수 실행결과를 전달하는 것이 아니라 함수자체(참조값)를 전달

  • case 2 - 화살표함수
setInterval(() => alert('안녕하세요.'), 1000);

  • case 3 - 인수 포함
function sayHi(who, phrase) {
  alert( who + ' 님, ' + phrase );
}

setInterval(sayHi, 1000, "홍길동", "안녕하세요."); // 홍길동 님, 안녕하세요.

3) clearInterval

setInterval을 호출하면 "인터벌아이디"가 반환(return값)된다.
이 "인터벌아이디"를 clearInterval함수에 넣어야만 동일한 함수의 스케줄링을 취소할 수 있다.

  • 인터벌아이디를 담은 변수를 전달
const intervalID = setInterval(/**/); 
// 여기서 setInterval함수가 실행됐기 때문에 타이머가 시작됨

clearInterval(intervalID);

  • ❌ 동일한 함수명 입력
const intervalId = setinterval(fnction foo () {
  console.log(1);
}, 1000);  //setInterval함수가 반환하는 인터벌아이디를 변수에 담음.

clearinterval(fnction foo () {
  console.log(1);
}, 1000); // 새로운 foo()함수를 생성한 꼴

=> function이라는 키워드를 사용하는 것은 clearInterval에서 또 다른 foo라는 함수를 생성하는 것이다(총 2개의 함수 존재).

=> 함수는 참조형 자료이기 때문에 두 함수의 reference는 다를 것임. 따라서 위의 방식으로는 clearInterval이 setInterval에서 만든 함수를 찾아서 지울 수 없다.



2. setTimeout - 한번 실행

  • setInterval과 문법 동일
  • clearTimeout(timerId)로 스케줄링 취소



3. 중첩 setTimeout - 반복 실행- 반복 실행

setInterval 대신 setTimeout을 중첩되게 작성하여 반복실행을 구현할 수 있다.

  • setInterval 사용
let i = 1;
setInterval(() => func(i++);
, 100);
  • 중첩setTimeout() 사용
let i = 1;
setTimeout(function run() {
  func(i++);
  setTimeout(run, 100);
}, 100);

🚩 setInterval 함수는 앞서 진행 중인 코드의 완료 유무와 관계없이 정해둔 시간 간격에 무조건 지정된 코드를 호출
=> 함수를 실행하는데 소모되는 시간도 시간간격에 포함시키기 때문.
=> 따라서 함수를 실행하는데 소모되는 시간이 시간간격보다 길 경우, 쉼 없이 연속 호출된다.

🚩 setTimeout 함수는 처음 지정된 간격만큼 기다린 후 지정된 코드를 실행한 뒤, 지정된 코드가 다 끝난 시점에 다시 setTimeout 함수를 호출
=> 이전 함수의 실행이 종료된 이후에 다음 함수 호출에 대한 스케줄링이 세워지기 때문.


4. 결론

  • 시간 지연이 있더라도 해당 코드의 동작을 모두 실행시키고 싶을 경우에는 setTimeout 함수를 사용

  • 중첩될 경우 무시되더라도 반드시 정해진 시간에 해당 코드를 실행시키고 싶다면 setInterval 함수를 사용



5. 초기 지연 없이 즉시 실행

setIntervalsetTimeout 모두 지정한 시간간격 이후 최초 호출이 발생한다.
=> 초기 지연시간 없이 함수를 바로 실행하려면 스케줄링함수 이전에 반복할 함수를 한번 호출해주어야 한다.

function printNumbers(from, to) {
  let current = from;

  function go() {
    alert(current);
    if (current == to) {
      clearInterval(timerId);
    }
    current++;
  }

  go(); // setInterval 이전에 반복할 함수 별도 호출
  let timerId = setInterval(go, 1000);
}

printNumbers(5, 10);

0개의 댓글