Languages/JavaScript

[HUFS/GnuVil] #23 타이머, Ajax

성중 2022. 11. 18. 03:01

타이머

자바스크립트는 타이머를 생성할 수 있는 setTimeout / setInterval, 타이머를 제거할 수 있는 clearTimeout / clearInterval  함수를 제공하며, 전역 객체의 메서드로 제공되는 호스트 객체로 비동기 처리 방식으로 동작한다

 

// 1초(1000ms) 후 타이머가 만료되면 콜백 함수가 호출된다.
setTimeout(() => console.log('Hi!'), 1000);

// 1초(1000ms) 후 타이머가 만료되면 콜백 함수가 호출된다.
// 이때 콜백 함수에 'Lee'가 인수로 전달된다.
setTimeout(name => console.log(`Hi! ${name}.`), 1000, 'Lee');

// 두 번째 인수(delay)를 생략하면 기본값 0이 지정된다.
setTimeout(() => console.log('Hello!'));

// 1초(1000ms) 후 타이머가 만료되면 콜백 함수가 호출된다.
// setTimeout 함수는 생성된 타이머를 식별할 수 있는 고유한 타이머 id를 반환한다.
const timerId = setTimeout(() => console.log('Hi!'), 1000);

// setTimeout 함수가 반환한 타이머 id를 clearTimeout 함수의 인수로 전달하여 타이머를
// 취소한다. 타이머가 취소되면 setTimeout 함수의 콜백 함수가 실행되지 않는다.
clearTimeout(timerId);

setTimeout 함수는 생성한 타이머가 만료되면 콜백 함수를 단 한 번 호출하며 clearTimeout으로 취소될 수 있다

 

let count = 1;

// 1초(1000ms) 후 타이머가 만료될 때마다 콜백 함수가 호출된다.
// setInterval 함수는 생성된 타이머를 식별할 수 있는 고유한 타이머 id를 반환한다.
const timeoutId = setInterval(() => {
  console.log(count); // 1 2 3 4 5
  // count가 5이면 setInterval 함수가 반환한 타이머 id를 clearInterval 함수의
  // 인수로 전달하여 타이머를 취소한다. 타이머가 취소되면 setInterval 함수의 콜백 함수가
  // 실행되지 않는다.
  if (count++ === 5) clearInterval(timeoutId);
}, 1000);

setInterval 함수는 생성한 타이머가 만료될 때마다 콜백 함수가 반복 호출되며 clearInterval로 취소될 수 있다

 

<!DOCTYPE html>
<html>
<body>
  <button>click me</button>
  <pre>일반 클릭 이벤트 카운터    <span class="normal-msg">0</span></pre>
  <pre>디바운스 클릭 이벤트 카운터 <span class="debounce-msg">0</span></pre>
  <pre>스로틀 클릭 이벤트 카운터   <span class="throttle-msg">0</span></pre>
  <script>
    const $button = document.querySelector('button');
    const $normalMsg = document.querySelector('.normal-msg');
    const $debounceMsg = document.querySelector('.debounce-msg');
    const $throttleMsg = document.querySelector('.throttle-msg');

    const debounce = (callback, delay) => {
      let timerId;
      return (...args) => {
        if (timerId) clearTimeout(timerId);
        timerId = setTimeout(callback, delay, ...args);
      };
    };

    const throttle = (callback, delay) => {
      let timerId;
      return (...args) => {
        if (timerId) return;
        timerId = setTimeout(() => {
          callback(...args);
          timerId = null;
        }, delay);
      };
    };

    $button.addEventListener('click', () => {
      $normalMsg.textContent = +$normalMsg.textContent + 1;
    });

    $button.addEventListener('click', debounce(() => {
      $debounceMsg.textContent = +$debounceMsg.textContent + 1;
    }, 500));

    $button.addEventListener('click', throttle(() => {
      $throttleMsg.textContent = +$throttleMsg.textContent + 1;
    }, 500));
  </script>
</body>
</html>

scroll / resize / input / mousemove 등의 이벤트는 짧은 간격으로 연속해서 발생해 성능 저하의 원인이 될 수 있다. 이 때 타이머를 응용해 디바운스스로틀로 과도한 호출을 방지할 수 있다

 

디바운스는 짧은 시간 간격으로 발생하는 이벤트를 그룹화해 마지막 한 번만 호출
스로틀은 일정 시간 간격으로 이벤트가 최대 한 번만 호출되도록 호출 주기를 생성

 

Ajax

Ajax(Asynchronous JavaScript and XML)란 자바스크립트를 사용해 브라우저가 서버에게 비동기 방식으로 데이터를 요청하고, 서버가 응답한 데이터를 수신해 웹페이지를 동적으로 갱신하는 프로그래밍 방식을 뜻하며, Wep API인 XMLHttpRequest 객체를 기반으로 동작한다

 

전통적 웹페이지의 생명 주기
Ajax

JSON은 클라이언트와 서버간 HTTP 통신을 위한 텍스트 데이터 포맷임, 언어 독립형 데이터 포맷이다

 

const obj = {
  name: 'Lee',
  age: 20,
  alive: true,
  hobby: ['traveling', 'tennis']
};

// 객체를 JSON 포맷의 문자열로 변환한다.
const json = JSON.stringify(obj);
console.log(typeof json, json);
// string {"name":"Lee","age":20,"alive":true,"hobby":["traveling","tennis"]}

// 객체를 JSON 포맷의 문자열로 변환하면서 들여쓰기 한다.
const prettyJson = JSON.stringify(obj, null, 2);
console.log(typeof prettyJson, prettyJson);
/*
string {
  "name": "Lee",
  "age": 20,
  "alive": true,
  "hobby": [
    "traveling",
    "tennis"
  ]
}

객체 리터럴과 유사한 형태로 JSON.stringfy 메서드로 객체를 JSON 문자열로 직렬화(Serializing) 할 수 있다

 

const obj = {
  name: 'Lee',
  age: 20,
  alive: true,
  hobby: ['traveling', 'tennis']
};

// 객체를 JSON 포맷의 문자열로 변환한다.
const json = JSON.stringify(obj);

// JSON 포맷의 문자열을 객체로 변환한다.
const parsed = JSON.parse(json);
console.log(typeof parsed, parsed);
// object {name: "Lee", age: 20, alive: true, hobby: ["traveling", "tennis"]}

JSON.parse 메서드는 JSON 포맷의 문자열을 객체로 변환하며 이를 역직렬화(Deserializing)라고 한다

 

// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();

// HTTP 요청 초기화
xhr.open('GET', '/users');

// HTTP 요청 헤더 설정
// 클라이언트가 서버로 전송할 데이터의 MIME 타입 지정: json
xhr.setRequestHeader('content-type', 'application/json');

// HTTP 요청 전송
xhr.send(JSON.stringify({ id: 1, content: 'HTML', completed: false }));

XMLHttpRequest 객체를 생성해 통신을 주고받을 수 있지만 보통 fetch나 axios 등을 사용한다

 

 내용은 위키북스의 '모던 자바스크립트 Deep Dive' 바탕으로 작성되었습니다.