본문 바로가기
Javascript

타이머, Throttle(쓰로틀), 디바운스(debounce)

by jennyiscoding 2022. 10. 4.

1. 타이머함수 종류

setTimeout, setInterval, clearTimeout, clearInterval이 있다. 

2. 타이머함수는 ECMASCRIPT함수인가?

아니다. 브라우저 환경과 Node.js환경에서 모두 전역 객체의 메서드로서 타이머 함수를 제공한다. 즉, 호스트객체이다. 

3. debounce 디바운스 (자바스크립트 딥다이브책)

짧은시간 간격으로 이벤트가 연속해서 발생하면 이벤트 핸들러를 호출하지 않다가 일정시간동안 이벤트가 더 이상 발생하지 않으면 이벤트 핸들러가 한번만 호출되도록 하는 것. 1초가 되기 전에 input을 하면은 if(alertTimer)부분에서 clearTimeout이 작동되어서 alert가 안뜨게 되는 것이다! 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="text">
    <div class="msg"></div>
    <script>
        const input = document.querySelector("input")
        const msg = document.querySelector(".msg")

        const debounce = (callback, delay) =>{
            let timerId;
            return event => {
                if(timerId) clearTimeout(timerId)
                timerId = setTimeout(callback,delay,event)
            }
        }
        input.oninput = debounce((e)=>{
            msg.textContent = e.target.value
        },300)
    </script>
</body>
</html>

4. throttle 스로틀

짧은시간 간격으로 이벤트가 연속해서 발생하더라도 일정 시간 간격으로 이벤트 핸들러가 최대 한번만 호출되도록 한다. setTimeout함수를 timerId라는 이름으로 저장을 해서, delay안에 timerId가 정의되어있으므로 return으로 함수를 나오므로 delay에 딱 한번만 호출되게 하는 것이다! 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .container {
            width: 300px;
            height: 300px;
            background-color: rebeccapurple;
            overflow: scroll;
        }
        .content {
            width: 300px;
            height: 1000vh;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="content"></div>
    </div>
    <div>
        일반 핸들러가 scroll 이벤트를 처리한 횟수
        <span class="normal-count">0</span>
    </div>
    <div>
        스로틀 핸들러가 scroll 이벤트를 처리한 횟수
        <span class="throttle-count">0</span>
    </div>
    <script>
        const $container = document.querySelector('.container')
        const $normalCount = document.querySelector('.normal-count')
        const $throttleCount = document.querySelector('.throttle-count')

        const throttle = (callback, delay) => {
            let timerId;
            return event => {
                if(timerId) return;
                timerId = setTimeout(()=>{
                    callback(event);
                    timerId = null;
                },delay, event)
            }
        }
        let normalCount = 0;
        $container.addEventListener('scroll',()=>{
            $normalCount.textContent = ++normalCount;
        });
        let throttleCount = 0;
        $container.addEventListener('scroll',throttle(()=>{
            $throttleCount.textContent = ++throttleCount;
        },100));
    </script>
</body>
</html>

 

QUESTION

1. setTimeout이라는 것을 실행하지 않고 변수로 정의했는데 실행되는 이유는 무엇인지!? 

const run = setTimeout(()=>{console.log('안녕')},1000)

함수는 호출해야하는데, 차이점이 무엇인지?

function hello(){
console.log('hello')
}
hello()

 

'Javascript' 카테고리의 다른 글

Symbol,Map,  (0) 2022.10.06
제너레이터  (0) 2022.10.06
오답노트) 3,2,1,끝이 1초에 한번 출력  (2) 2022.10.04
이벤트루프, 동기,비동기,Promise  (0) 2022.10.04
프로토타입  (0) 2022.10.02