๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive ๋์์ 41์ฅ ํ์ด๋จธ๋ฅผ ์ ๋ฆฌํ์์ต๋๋ค.
ํจ์๋ฅผ ๋ช ์์ ์ผ๋ก ํธ์ถํ์ง ์๊ณ ์ผ์ ์๊ฐ์ด ๊ฒฝ๊ณผ๋ ์ดํ์ ํธ์ถ๋๋๋ก ํจ์ ํธ์ถ์ ์์ฝํ๋ ค๋ฉด ํ์ด๋จธ ํจ์๋ฅผ ์ฌ์ฉํ๋ค. ์ด๋ฅผ ํธ์ถ ์ค์ผ์ค๋ง์ด๋ผ ํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ ํ์ด๋จธ๋ฅผ ์์ฑํ ์ ์๋ ํ์ด๋จธ ํจ์ setTImeout
๊ณผ setInterval
, ํ์ด๋จธ๋ฅผ ์ ๊ฑฐํ ์ ์๋ ํ์ด๋จธ ํจ์ clearTimeout
๊ณผ clearInterval
์ ์ ๊ณตํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ฑ๊ธ ์ค๋ ๋๋ก ๋์ํ๊ณ ๋จ ํ๋์ ์คํ ์ปจํ
์คํธ ์คํ์ ๊ฐ๊ธฐ ๋๋ฌธ์ ๋ ๊ฐ์ง ์ด์์ ํ์คํฌ๋ฅผ ๋์์ ์คํํ ์ ์๋ค. ์ด๋ฐ ์ด์ ๋ก setTImeout
๊ณผ setInterval
์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค.
setTimeout
ํจ์๋ ๋ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ์๊ฐ์ผ๋ก ๋จ ํ ๋ฒ ๋์ํ๋ ํ์ด๋จธ๋ฅผ ์์ฑํ๋ค. ์ดํ ํ์ด๋จธ๊ฐ ๋ง๋ฃ๋๋ฉด ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ฐ์ ์ฝ๋ฐฑ ํจ์๊ฐ ํธ์ถ๋๋ค. ์ฆ, setTimeout ํจ์์ ์ฝ๋ฐฑ ํจ์๋ ๋ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ์๊ฐ ์ดํ ๋จ ํ ๋ฒ ์คํ๋๋๋ก ํธ์ถ ์ค์ผ์ค๋ง๋๋ค.
// setTimeout ํจ์๋ ์์ฑ๋ ํ์ด๋จธ๋ฅผ ์๋ณํ ์ ์๋ ๊ณ ์ ํ ํ์ด๋จธ id๋ฅผ ๋ฐํํ๋ค.
const timerId = setTimeout(() => console.log('Hi!'), 1000);
// ํ์ด๋จธ id๋ฅผ clearTimeout ํจ์์ ์ธ์๋ก ใ
ใ
ใด๋ฌํ์ฌ ํ์ด๋จธ๋ฅผ ์ทจ์ํ๋ค.
clearTimeout(timerId)
`setInterval
ํจ์๋ ๋ ๋ฒ์จฐ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ์๊ฐ์ผ๋ก ๋ฐ๋ณต ๋์ํ๋ ํ์ด๋จธ๋ฅผ ์์ฑํ๋ค. ์ดํ ํ์ด๋จธ๊ฐ ๋ง๋ฃ๋ ๋๋ง๋ค ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ํจ์๊ฐ ๋ฐ๋ณต ํธ์ถ๋๋ค. ์ด๋ ํ์ด๋จธ๊ฐ ์ทจ์๋ ๋๊น์ง ๊ณ์๋๋ค!
let count = 1
const timeoutId = sestInterval(() => {
console.log(count) // 1 2 3 4 5
// count๊ฐ 5์ด๋ฉด ํ์ด๋จธ๋ฅผ ์ทจ์ํ๋ค.
if(count++ === 5) clearInterval(timeoutId)
}, 1000)
๋๋ฐ์ด์ค์ ์ค๋กํ์ ์งง์ ์๊ฐ ๊ฐ๊ฒฉ์ผ๋ก ์ฐ์ํด์ ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ฅผ ๊ทธ๋ฃนํํด์ ๊ณผ๋ํ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ๋ฐฉ์งํ๋ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ด๋ค.
๋๋ฐ์ด์ค๋ ์งง์ ์๊ฐ ๊ฐ๊ฒฉ์ผ๋ก ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ฅผ ๊ทธ๋ฃนํํด์ ๋ง์ง๋ง์ ํ ๋ฒ๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ํธ์ถ๋๋๋ก ํ๋ค.
const $input = document.querySelector('input')
const $msg = document.querySelector('.msg')
const debounce = (callback, delay) => {
let timerId
// debounce ํจ์๋ timerId๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ฅผ ๋ฐํํ๋ค.
return event => {
// delay๊ฐ ๊ฒฝ๊ณผํ๊ธฐ ์ด์ ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด์ ํ์ด๋จธ๋ฅผ ์ทจ์ํ๊ณ ์๋ก์ด ํ์ด๋จธ๋ฅผ ์ฌ์ค์ ํ๋ค.
if (timerId) clearTimeout(timerId)
timerId = setTimeout(callback, delay, event)
}
}
// debounce ํจ์๊ฐ ๋ฐํํ๋ ํด๋ก์ ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋ก๋๋ค.
// 300ms ๋์ input ์ด๋ฒคํธ๊ฐ ๋ ์ด์ ๋ฐ์ํ์ง ์์ผ๋ฉด ํ ๋ฒ๋ง ํธ์ถ๋๋ค.
$input.oninput = debounce(e => {
$msg.textContent = e.target.value
}, 300)
์ค๋กํ์ ์งค์ ์๊ฐ ๊ฐ๊ฒฉ์ผ๋ก ์ฐ์ํด์ ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ฅผ ๊ทธ๋ฃนํํด์ ์ผ์ ์๊ฐ ๋จ์๋ก ์ด๋ฒคํธ๊ฐ ํธ์ถ๋๋๋ก ํธ์ถ ์ฃผ๊ธฐ๋ฅผ ๋ง๋ ๋ค.
const throttle = (callback, delay) => {
let timerId
// throttle ํจ์๋ timerId๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ฅผ ๋ฐํํ๋ค.
return event => {
// delay๊ฐ ๊ฒฝ๊ณผํ๊ธฐ ์ด์ ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌด๊ฒ๋ ํ์ง ์๋ค๊ฐ delay๊ฐ ๊ฒฝ๊ณผํ์ ๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ก์ด ํ์ด๋จธ๋ฅผ ์ฌ์ค์ ํ๋ค.
// ๋ฐ๋ผ์ delay ๊ฐ๊ฒฉ์ผ๋ก callback์ด ํธ์ถ๋๋ค.
if(timerId) return
timerId = setTimeout(() => {
callback(event)
timerId = null
}, delay, event)
}
}
์ด๋ฐ ์ค๋กํ์ ๋ฌดํ ์คํฌ๋กค UI ๊ตฌํ ๋๋ scroll ์ด๋ฒคํธ ์ฒ๋ฆฌ์ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค.
Ref
- ์ด์ ๋ชจ ์ , โ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Diveโ, ์ํค๋ถ์ค
- setTimeout๊ณผ setInterval์ ์ด์ฉํ ํธ์ถ ์ค์ผ์ค๋ง