[모던 JavaScript 튜토리얼] - [6.8] setTimeout과 setInterval을 이용한 호출 스케줄링

IRISH·2024년 2월 3일
0

JS

목록 보기
63/80


학습 내용

  • setInterval(func, delay, ...args)과 setTimeout(func, delay, ...args)은 delay밀리초 후에 func을 규칙적으로, 또는 한번 실행하도록 해줍니다.
  • setInterval·setTimeout을 호출하고 반환받은 값을 clearInterval·clearTimeout에 넘겨주면 스케줄링을 취소할 수 있습니다.
    • 참고로 스케줄링을 취소 안해주면, setInterval과 setTimeOut에 대한 메모리가 계속 남겨있음
      • 가비지 컬렉션 대상에도 걸리지 않음
        • 따라서, 반드시 스케줄링을 취소하자!
  • 중첩 setTimeout을 사용하면 setInterval을 사용한 것보다 유연하게 코드를 작성할 수 있습니다. 여기에 더하여 지연 간격 보장이라는 장점도 있습니다.
  • 대기 시간이 0인 setTimeout(setTimeout(func, 0) 혹은 setTimeout(func))을 사용하면 ‘현재 스크립트의 실행이 완료된 후 가능한 한 빠르게’ 원하는 함수를 호출할 수 있습니다.
  • 지연 없이 중첩 setTimeout을 5회 이상 호출하거나 지연 없는 setInterval에서 호출이 5회 이상 이뤄지면, 4밀리초 이상의 지연 간격이 강제로 더해집니다. 이는 브라우저에만 적용되는 사항이며, 하위 호환성을 위해 유지되고 있습니다.

스케줄링 메서드를 사용할 땐 명시한 지연 간격이 보장되지 않을 수도 있다는 점에 유의해야 합니다.

아래와 같은 상황에서 브라우저 내 타이머가 느려지면 지연 간격이 보장되지 않습니다.

  • CPU가 과부하 상태인 경우
  • 브라우저 탭이 백그라운드 모드인 경우
  • 노트북이 배터리에 의존해서 구동 중인 경우

이런 상황에서 타이머의 최소 지연 시간은 300밀리초에서 심하면 1,000밀리초까지 늘어납니다. 연장 시간은 브라우저나 구동 중인 운영 체제의 성능 설정에 따라 다릅니다.

실습 코드

/* 실행 후 N ms초 뒤에 함수 실행 */
function sayHi() {
    console.log('안녕하세요.');
}

function sayPcy(){
    console.log('내 이름은 PCY 입니다.');
}

let timerId1 = setTimeout(sayPcy, 500); // console.log('내 이름은 PCY 입니다.');
let timerId2 = setTimeout(sayHi, 1000); // 안녕하세요.

/* 인자를 받아서 실행 후 N ms초 뒤에 함수 실행 */
function manyArgs(A, B){
    console.log(A + "시의 온도는 " + B + "도입니다." );
}

// 방법 A, B 모두 결과 = 서울시의 온도는 23도입니다.
// 되도록 문자열 사용시, 방법 A보다 방법 B를 사용할 것
let timerId3 = setTimeout(manyArgs, 1500, "서울", 23); // 방법 A
let timerId4 = setTimeout(() => manyArgs("서울", 23), 2000); // 방법 B

// ---------------------------------------------------------

/* setInterval 과 clearInterval */
// 2초 간격으로 메시지를 보여줌
let timerId5 = setInterval(() => console.log('째깍'), 2000);

// 5초 후에 정지
setTimeout(() => { clearInterval(timerId5); console.log('정지'); }, 5000);

과제

→ 1번

/* 
일초 간격으로 숫자 출력하기

from에 명시한 숫자부터 to에 명시한 숫자까지 출력해주는 
함수 printNumbers(from, to)를 만들어보세요. 
숫자는 일 초 간격으로 출력되어야 합니다.

두 가지 방법을 사용해 함수를 만드셔야 합니다.
1. setInterval을 이용한 방법
2. 중첩 setTimeout을 이용한 방법
*/

// 방법 1 [setInterval을 이용한 방법]
function printNumbers(from, to){
    let current = from;

    let timerId = setInterval(function() {
        console.log(current);
        if (current == to) {
        clearInterval(timerId);
        }
        current++;
    }, 1000);
}
printNumbers(1, 6);

// ================================================

// 방법 2 [중첩 setTimeout을 이용한 방법]
function printNumbers2(from, to) {
    let current = from;
  
    setTimeout(function go() {
      console.log(current);
      if (current < to) {
        setTimeout(go, 1000);
      }
      current++;
    }, 1000);
}
  
  // usage:
  printNumbers2(5, 10);

→ 2번

/* 
setTimeout 은 무엇을 보여줄까요?
중요도: 5
아래 코드에선 setTimeout을 이용해 호출을 스케줄링하고 있습니다. 
그런데 그 아래 코드에선 실행 시간이 100ms 이상 걸리는 무거운 작업을 하고 있네요.

이런 경우 setTimeout에 넘겨준 함수는 언제 실행될까요?

반복문 실행 후
반복문 실행 전
반복문이 실행되는 시점
얼럿창엔 어떤 값이 출력될까요?
============================================================
let i = 0;

setTimeout(() => console.log(i), 100); // ?

// 아래 반복문을 다 도는 데 100ms 이상의 시간이 걸린다고 가정합시다.
for(let j = 0; j < 100000000; j++) {
  i++;
}
*/

// setTimeout은 현재 실행 중인 코드의 실행이 종료되었을 때 실행됩니다.
// 반복문 실행이 종료되고 난 후 i는 100000000이 되므로, 얼럿창엔 100000000이 출력됩니다.

let i = 0;

setTimeout(() => console.log(i), 100); // 100000000이 출력됩니다.

// assume that the time to execute this function is >100ms
for(let j = 0; j < 100000000; j++) {
  i++;
}

느낀점

  • setTimeout 과 setInterval을 두고 보았을 때, 가급적 setInterval보다는 중첩 setTimeout을 사용하는 것이 더 좋을 것 같다.
  • 테스트 코드를 할 때나 실제 프로젝트 운영에 있어서도 자주 사용할 것 같다.
    • 동기나 비동기 때 자주 사용할 가능성이 높은 실무 프로젝트에서 사용할 가능성이 높겠다.
    • 보안, 금융, 국방 등?
profile
#Software Engineer #IRISH

0개의 댓글