본문 바로가기
언어/JavaScript

[JS] setInterval, setTimeout

by 이민우 2022. 7. 26.
728x90
반응형

자바스크립트에서는 setInterval, setTimeout 함수를 통해 스케줄러를 지원한다.

 

두 함수의 차이는 아래와 같다.

  • setInterval : 지정된 주기로 특정 코드를 실행한다.
  • setTimeout : 지정된 초가 지난 후 특정 코드를 1회 실행한다.

 

즉 setInterval은 주기적으로 지정된 코드를 계속 실행하고, setTimeout은 한 번 실행 후 멈추게 된다.

 

F12를 누른 후 아래 코드를 복사하여 실행해보면 차이를 명확하게 알 수 있다.

setTimeout(function() { console.log('timeout'); }, 1000);
setInterval(function() { console.log("interval"); }, 1000);

위 코드 실행 시 timeout이라는 문구는 한 번만 출력되는 반면, interval이라는 문구는 1초 단위로 계속해서 출력됨을 확인할 수 있다.

 

setTimeout은 setInterval처럼 주기적으로 실행되도록 만들 수 없느냐? 그건 또 아니다. 아래와 같이 timeOut 안에 timeOut 코드를 넣으면 setTimeout도 setInterval처럼 주기적으로 실행되도록 생성할 수 있다.

setTimeout(function timeoutTest() { 
    console.log("timeout");
    setTimeout(timeoutTest, 1000);
}, 1000);

 

setTimeout을 사용해도 setInterval과 같은 효과를 낼 수 있다는 건 알겠는데, 왜 굳이 그렇게 해야할까? 그냥 한 줄로 설정을 끝낼 수 있는 setInterval을 사용하면 안되는 걸까?

 

물론 그래도 되긴 하지만, 두 함수에는 무시할 수 없는 차이점이 존재한다.

 

setInterval은 설정된 함수의 실행시간에 관계 없이, 간격으로 설정된 시간이 지나면 곧바로 다시 함수를 실행시킨다.

그에 반해 setTimeout은 함수가 끝나게 되면 다시 간격대로 함수를 실행시킨다.

 

예를 들어 setInterval과 setTimeout을 1초 간격으로 설정하여 2초가 걸리는 함수를 실행시킬 경우, setInterval 내 함수는 1초마다, setTimeout은 3초마다 실행되는 것이다.

 

이 내용은 아래 예시를 통해 확인이 가능하다.

setInterval(function() { 
    console.log(new Date().getSeconds() + ' interval');
    for(i=0; i<100000000; i++) {}
}, 1000)

위 코드를 실행시킬 경우 콘솔에 정화히 1초를 간격으로 문구가 찍힘을 확인할 수 있다.

 

그리고 다음과 같은 setTimeout 코드는 1초가 아닌 보다 긴 간격으로 실행됨을 확인할 수 있다.

setTimeout(function timeoutTest() { 
    console.log(new Date().getSeconds() + " timeout");
    for(i=0; i<100000000; i++) {}
    setTimeout(timeoutTest, 1000);
}, 1000);

 

 

위의 함수들을 잘 사용하면 스케줄러가 필요한 상황에서 얼마든지 스케줄러를 적용할 수 있다.

아래는 setInterval을 이용한 디지털 시계 예시이다.

 

Web Clock
<html lang="ko">
    <head>
        <meta charset="utf-8">
        <title>Web Clock</title>
        <style>
            .inner_html_body {
                background-color: white;
            }
            .date {
                width: 100%;
                height: 40%;
                display: flex;
                justify-content: center;
                align-items: flex-end;
                color: black;
                text-align: center;
                font-size: 35px;
            }
            .clock {
                width: 100%;
                height: 20%;
                display: flex;
                justify-content: center;
                align-items: flex-start;
                color: black;
                text-align: center;
                font-size: 80px;
            }
            .time_left {
                width: 100%;
                height: 30%;
                display: flex;
                justify-content: center;
                align-items: flex-start;
                color: black;
                text-align: center;
                font-size: 50px;
            }
        </style>
    </head>
    <body class='inner_html_body'>
        <div id="clock_div" class="clock_div">
            <div id="date" class="date"></div>
            <div id="clock" class="clock"></div>
            <div id="time_left" class="time_left"></div>
        </div>
        <script>
            time_out = 3600*18;

            date_box = document.getElementById("date")
            clock_box = document.getElementById("clock")
            time_left = document.getElementById("time_left")

            function fillzero(num) {
                // 1 => 01 로 바꿔주기
                return ('00' + num).slice(-2)
            }

            function updateClock() {
                var time = new Date();

                var year = time.getFullYear(); // 연
                var month = fillzero(time.getMonth() + 1); // 월
                var date = fillzero(time.getDate()); // 일
                var day = time.getDay(); // 요일
                var day_arr = ['일', '월', '화', '수', '목', '금', '토']

                var hour = time.getHours(); // 시
                var minute = time.getMinutes(); // 분
                var second = time.getSeconds(); // 초

                time_left_sec = time_out - hour*3600 - minute*60 - second

                var ampm = "am"
                if(hour >= 12) {
                    ampm = "pm"
                    // 13시 부터 1시로 표기
                    if(hour != 12)
                        hour -=12;
                }
                
                hour = fillzero(hour)
                minute = fillzero(minute)
                second = fillzero(second)

                date_text = year + "-" + month + "-" + date + " " + day_arr[day] + "요일";
                time_text =  hour + ":" + minute + ":" + second + " " + ampm
                
                if(time_left_sec < 0)
                    time_left_text = "퇴근 완료!"
                else if(hour < 9 && ampm == 'am')
                    time_left_text = "출근 전"
                else if(time_left_sec > 0)
                    time_left_text = "퇴근까지 " + time_left_sec + "초"

                date_box.innerText = date_text;
                clock_box.innerText = time_text;
                time_left.innerText = time_left_text;
            }

            updateClock(); // 시작 시 실행
            setInterval(updateClock, 1000); // 이후 1초마다 갱신
        </script>
    </body>
</html>

 

혹은 스톱워치 같은 것도 얼마든지 생성이 가능하다.

Web stopwatch
<html lang="ko">
    <head>
        <meta charset="utf-8">
        <title>Web stopwatch</title>
        <style>
            .inner_html_body {
                background-color: white;
            }
            .stopwatch {
                width: 100%;
                height: 50%;
                display: flex;
                justify-content: center;
                align-items:flex-end;
                color: black;
                text-align: center;
                font-size: 80px;
            }
            .button_box {
                width: 100%;
                height: 20%;
                display: flex;
                justify-content: center;
                align-items: flex-start;
                color: black;
                text-align: center;
                font-size: 80px;
            }

            .btn {
                width: 90px;
                height: 60px;
                margin: 10px;
                font-size: 5px;
            }
        </style>
    </head>
    <body class='inner_html_body'>
        <div id="stopwatch" class="stopwatch"></div>
        <div id="button_box" class="button_box">
            <input type="button" id="reset" onclick="reset()" value="초기화" class="btn" disabled style="color:red">
            <input type="button" id="start" onclick="start()" value="시작" class="btn" style="color:black">
            <input type="button" id="stop" onclick="stop()" value="중지" disabled class="btn" style="color:blue">
        </div>
        <script>
            stopwatch_box = document.getElementById("stopwatch")
            stopwatch_hour = 0
            stopwatch_min = 0
            stopwatch_sec = 0
            stopwatch_millisec = 0
            isActive=false

            show();

            function show() {
                time_text = fillzero(stopwatch_hour) + ":" + fillzero(stopwatch_min) + ":" + fillzero(stopwatch_sec) + ":" + fillzero(stopwatch_millisec)
                stopwatch_box.innerText = time_text;
            }

            function reset() {
                stopwatch_hour = 0
                stopwatch_min = 0
                stopwatch_sec = 0
                stopwatch_millisec = 0

                isActive=false
                
                document.getElementById("reset").disabled=false
                document.getElementById("start").disabled=false
                document.getElementById("stop").disabled=true

                show()
            }

            function start() {
                isActive=true
                
                document.getElementById("reset").disabled=true
                document.getElementById("start").disabled=true
                document.getElementById("stop").disabled=false
            }

            function stop() {
                isActive=false
                
                document.getElementById("reset").disabled=false
                document.getElementById("start").disabled=false
                document.getElementById("stop").disabled=true
            }

            function fillzero(num) {
                // 1 => 01 로 바꿔주기
                return ('00' + num).slice(-2)
            }

            function active() {
                if(!isActive)
                    return
                
                stopwatch_millisec += 1

                if(stopwatch_millisec == 100) {
                    stopwatch_sec += 1
                    stopwatch_millisec = 0
                }

                if(stopwatch_sec == 60) {
                    stopwatch_min += 1
                    stopwatch_sec = 0
                }

                if(stopwatch_min == 60) {
                    stopwatch_hour += 1
                    stopwatch_min = 0
                }
                show()
            }

            setInterval(active, 10);
        </script>
    </body>
</html>
728x90
반응형

'언어 > JavaScript' 카테고리의 다른 글

[IFrame] 부모-자식 간 통신  (0) 2021.10.16
[Ajax] Ajax를 활용한 통신  (0) 2021.10.16
[JQury] 제이쿼리 사용법  (0) 2021.10.14