😎 난 타이머도 제대로 모른다.
실행컨텍스트와 이벤트루프에 대해 공부하면서 뼈저리게 생각한 부분입니다.
타이머는 어떻게 동작하는지 세부적으로 나눠서 생각하면 정말 어려워요
하지만 뭔가 헷갈리는게 있을 땐 일단 모던 자바스크립트 딥다이브 책을 펴보면
얼추 내가 궁금해하는게 이미 명쾌하게 적혀있다.
내가 기억을 못하는 것일 뿐...
물론.. 진짜 딥다이브에도 안나와있는 문제 상황들도 간혹 있긴하지만
그런 경우엔 눈물 흘리면서 영어의 파도를 헤쳐나가 답을 찾아야하죠..
다행히 타이머의 경우엔 제가 제대로 안읽은거지
딥다이브에서 아주 상세하게 설명해주고 있었습니다.
오늘은 딥다이브를 참고해서 타이머를 다시 정리하는 시간을 가져봅니다.
😎호출 스케줄링을 알아야한다.
<ref *1> Object [global] {
global: [Circular *1],
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
structuredClone: [Getter/Setter],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
atob: [Getter/Setter],
btoa: [Getter/Setter],
performance: [Getter/Setter],
fetch: [AsyncFunction: fetch],
crypto: [Getter]
}
함수를 명시적으로 호출하면 함수는 즉시 실행됩니다.
만약에 함수를 명시적으로 호출하지 않고. 일정시간이 지난 이후에 호출되도록
함수 호출을 예약하려면 타이머 함수를 사용하며
이것을 호출 스케줄링이라고 합니다.
타이머함수는 ECMAScript의 표준에 포함되어있지는 않지만
node.js, 브라우저 환경에서 전역 객체의 메서드로 제공되기 때문에
타이머함수는 호스트 객체입니다.
그 증거로.. Node.js환경에서 console.log(globalThis)를 찍어보면
저렇게 전역객체가 가지고있는 프로퍼티들이 쭉 나열되는데
setInterval, setTimeout등 타이머 함수들이 포함되어있는 것을 확인할 수 있습니다.
😎setInterval과 setTimeout은...
setInterval(() => console.log('인터벌폼미쳤다'), 1000);
/*
인터벌폼미쳤다
인터벌폼미쳤다
인터벌폼미쳤다
인터벌폼미쳤다
인터벌폼미쳤다
인터벌폼미쳤다
*/
모두 일정 시간이 경과된 이후에 콜백 함수가 호출되도록 타이머를 생성하는 역할을 합니다.
타이머 함수 setTimeout과 setInterval은 생성한 타이머가 "만료"되면 콜백 함수가 호출됩니다.
setTimeout 함수의 콜백함수는 타이머가 만료되면 단 한번 호출되고
setInterval은 타이머가 만료될때마다 반복호출됩니다.
계속 반복해야하는 작업이 있을때 interval을 쓰면 좋...나?
😎setTimeout
const timeoutId = setTimeout(func , delay , param1, param2)
문법은 다음과 같다.
콜백 함수 대신 코드를 문자열로 전달할 수 있는데...
솔직히 어떻게 쓰는지는 잘 모르겠습니다.
eval 함수랑 유사하게 동작하게되니까 권장되지는 않는다네요
delay는 타이머 만료 시간(밀리초 ms)로 숫자를 받습니다.
만약 delay가 4ms 이하이면 최소 지연시간 4ms가 지정됩니다.
그리고 좀 충격적이었던게 호출 스케줄링 된 콜백 함수에 전달해야할 인수가 존재하면
세번째 이후의 인수로 전달할 수 있습니다(IE 9 이하에서는 전달 불가)
setTimeout 함수는 생성된 타이머를 식별할 수 있는 고유한 타이머 id를 반환합니다.
(몰랐음)
setTimeout 함수가 반환한 타이머 id는 브라우저 환경인 경우 숫자
Node.js 환경인 경우엔 객체입니다.
😎clearInterval
function timer () {
let timerId
timerId = setTimeout(() => {
console.log("실행안댐")
}, 3000);
clearTimeout(timerId)
}
timer()
clearInterval함수는 setInterval 함수가 반환한 타이머 id를 인자로 전달받아
타이머를 취소시킬 수 있습니다.
그걸 이용해서 이런 코드를 작성하면
아무일도 일어나지 않습니다.
clearTimeout에 의해 setTimeout이 취소된것
이것을 이용해 디바운스를 구현할 수 있습니다.
😎디바운스
scroll, resize, input, mousemove같은 이벤트는 짧은 시간에 연속적으로 발생합니다.
이러한 이벤트에 바인딩한 이벤트 핸들러는 과도하게 호출되어서 성능에 문제를 일으킬 수도 있어요
디바운스는 짧은 시간 간격으로 이벤트가 연속해서 발생하면 이벤트 핸들러를 호출하지않다가..
일정 시간이 경과한 이후에 이벤트 핸들러가 한번만 호출되도록 합니다.
대충 그림으로 보면 저런 느낌
그리 어렵진 않은 느낌이네요 하지만 구현은 조금 극혐임
input 이벤트는 사용자가 텍스트 입력 필드에 값을 입력할 때마다 연속해서 발생합니다.
만약 값을 입력할때마다 ajax요청을 보내면 너무 비효율적이니
일정시간동안 값을 입력하지 않으면 입력 완료로 취급하고자 한다.
😎스로틀
스로틀은 짧은 시간 간격으로 이벤트가 연속해서 발생하더라도
일정 시간 간격으로 이벤트 핸들러가 최대 한번만 호출되도록 한다.
따라서 스로틀은 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 일정 시간 단위로
이벤트 핸들러가 호출되도록 호출 주기를 만든다.
그룹화 해서 호출주기를 만드는게 핵심이네요
계속 이벤트가 발생하는 경우 디바운스보다 스로틀이 더 자주 호출될 수 도 있겠네요
대략..이런느낌...
어떤게 좋냐기보다는 상황에 따라 좋은 방법이 나눠질 수 있겠네요
스로틀 역시 직접..구현할 수 있지만 극혐이니까 넘어가겠습니다.
근데 이 스로틀을 활용해서 스크롤 이벤트처리나 무한 스크롤 UI 구현을 할 수 있대요
개쩌네요
Lodash의 throttle 함수나 Underscore throttle 함수가 제공되니까
그거 쓰라고하네요
반응형
'javascript' 카테고리의 다른 글
자바스크립트 this 디스합니다. 비트주세요 (0) | 2023.03.16 |
---|---|
프로미스를 회처럼 날로 먹는 방법 (3) | 2023.03.15 |
이벤트 루프와 블록 컨텍스트를 알아보자. (0) | 2023.03.10 |
생존법칙1 reduce 메서드를 이해해라. (0) | 2023.03.09 |
이터러블과 이터레이터를 이해하는 방법 (0) | 2023.03.06 |