๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
javascript/๐Ÿ“– study

[9์ฃผ์ฐจ ์Šคํ„ฐ๋””]41์žฅ-ํƒ€์ด๋จธ

by HomieKim 2022. 3. 27.

ํƒ€์ด๋จธ

ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง

  • ํ•จ์ˆ˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ผ์ • ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผ๋œ ์ดํ›„์— ํ˜ธ์ถœ์„ ์˜ˆ์•ฝํ•˜๋Š” ๊ฒƒ์„ ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง ์ด๋ผ ํ•จ
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํƒ€์ด๋จธ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณต
    • ํƒ€์ด๋จธ ์ƒ์„ฑ ํ•จ์ˆ˜ : setTimeout, setInterval
    • ํƒ€์ด๋จธ ์ œ๊ฑฐ ํ•จ์ˆ˜ : clearTimeout, clearInterval
  • ํƒ€์ด๋จธ ํ•จ์ˆ˜๋Š” ECMAScript ์‚ฌ์–‘์— ์ •์˜๋œ ๋นŒํŠธ์ธ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • Node.js ํ™˜๊ฒฝ์—์„œ ์ „์—ญ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ ์ฆ‰, ํ˜ธ์ŠคํŠธ ๊ฐ์ฒด
  • ํƒ€์ด๋จธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ƒ์„ฑํ•œ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๋™์ž‘ ๋ฐฉ์‹
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ(single thread)๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ด๋จธ ํ•จ์ˆ˜ setTimeout, setInterval์€ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ ํ•œ๋‹ค.

ํƒ€์ด๋จธ ํ•จ์ˆ˜

setTimeout/ clearTimeout

  • setTimeout ํ•จ์ˆ˜๋Š” ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜, ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ์‹œ๊ฐ„, ์ „๋‹ฌํ•ด์•ผ ํ•  ์ธ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ์„ธ๋ฒˆ ์งธ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜์—ฌ ์‚ฌ์šฉ
  • ์ „๋‹ฌ ๋ฐ›์€ ์‹œ๊ฐ„์œผ๋กœ ๋‹จ ํ•œ ๋ฒˆ ๋™์ž‘ํ•˜๋Š” ํƒ€์ด๋จธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ(ํ•œ๋ฒˆ ์‹คํ–‰)
// 1์ดˆ(1000ms) ํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
setTimeout(() => console.log('Hi!'), 1000);

// 1์ดˆ(1000ms) ํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
// ์ด๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— 'Lee'๊ฐ€ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ๋‹ค.
setTimeout(name => console.log(`Hi! ${name}.`), 1000, 'Lee');

// ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜(delay)๋ฅผ ์ƒ๋žตํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’ 0์ด ์ง€์ •๋œ๋‹ค.
setTimeout(() => console.log('Hello!'));
  • setTimeout์€ ์ƒ์„ฑ๋œ ํƒ€์ด๋จธ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ์œ ํ•œ ํƒ€์ด๋จธ id๋ฅผ ๋ฐ˜ํ™˜
  • ํƒ€์ด๋จธ id๋ฅผ clearTimeout ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํƒ€์ด๋จธ๋ฅผ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋‹ค.
const timerId = setTimeout(() => console.log('excute call back'), 1000);
// clearTimeout์œผ๋กœ ์ทจ์†Œํ•˜๋ฉด setTimeout์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
clearTimeout(timerId);

setInterval / clearInterval

  • setInterval ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ์ธ์ˆ˜๋Š” setTimeout๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
  • ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜, ๋‘๋ฒˆ์งธ ์ธ์ˆ˜ ์‹œ๊ฐ„, ์ „๋‹ฌํ•  ์ธ์ž๊ฐ€ ์žˆ๋‹ค๋ฉด ์„ธ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ
  • setIntervalํ•จ์ˆ˜๋Š” ์ „๋‹ฌ ๋ฐ›์€ ์‹œ๊ฐ„์œผ๋กœ ๋ฐ˜๋ณต ๋™์ž‘ํ•˜๋Š” ํƒ€์ด๋จธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ฆ‰, ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋  ๋•Œ๋งˆ๋‹ค ์ „๋‹ฌ ๋ฐ›์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰ ๋จ
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ณ ์œ ํ•œ ํƒ€์ด๋จธ id๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ clearInterval๋กœ ์ทจ์†Œ ๊ฐ€๋Šฅ
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);

๋””๋ฐ”์šด์Šค์™€ ์Šค๋กœํ‹€

  • scroll, resize, input, mousemove ๊ฐ™์€ ์ด๋ฒคํŠธ๋Š” ์งง์€ ์‹œ๊ฐ„ ์—ฐ์†์ ์œผ๋กœ ๋ฐœ์ƒํ•˜์—ฌ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๊ณผ๋„ํ•˜๊ฒŒ ํ˜ธ์ถœ๋˜์–ด ์„ฑ๋Šฅ์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ๋””๋ฐ”์šด์Šค์™€ ์Šค๋กœํ‹€์€ ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ทธ๋ฃนํ™”ํ•ด์„œ ๊ณผ๋„ํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ํ˜ธ์ถœ์„ ๋ฐฉ์ง€ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ด๋‹ค.

๋””๋ฐ”์šด์Šค (debounce)

  • ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋‹ค๊ฐ€ ์ผ์ • ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผํ•œ ์ดํ›„์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ ๋˜๋„๋ก ํ•œ๋‹ค.

    ์ฆ‰, ๋””๋ฐ”์šฐ์Šค๋Š” ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ทธ๋ฃนํ™” ํ•ด์„œ ๋งˆ์ง€๋ง‰์— ํ•œ ๋ฒˆ๋งŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜๋„๋ก ํ•œ๋‹ค.

  • ๊ตฌํ˜„ ์˜ˆ์‹œ
const debounce = (callback, delay) => {
  let timerId;
  // debounce ํ•จ์ˆ˜๋Š” timerId๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  return event => {
    // delay๊ฐ€ ๊ฒฝ๊ณผํ•˜๊ธฐ ์ด์ „์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด์ „ ํƒ€์ด๋จธ๋ฅผ ์ทจ์†Œํ•˜๊ณ 
    // ์ƒˆ๋กœ์šด ํƒ€์ด๋จธ๋ฅผ ์žฌ์„ค์ •ํ•œ๋‹ค.
    // ๋”ฐ๋ผ์„œ delay๋ณด๋‹ค ์งง์€ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด callback์€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค.
    if (timerId) clearTimeout(timerId);
    timerId = setTimeout(callback, delay, event);
  };
};
  • resize ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ, ์ž…๋ ฅ ๊ฐ’์œผ๋กœ ajax ์š”์ฒญ, ๋ฒ„ํŠผ ์ฃผ์˜ค๋ณต ํด๋ฆญ ๋ฐฉ์ง€ ๋“ฑ ํ™œ์šฉ ๊ฐ€๋Šฅ

์Šค๋กœํ‹€ (throttle)

  • ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์ผ์ • ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ตœ๋Œ€ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๋„๋ก ํ•œ๋‹ค.

    ์ฆ‰, ์ผ์ • ์‹œ๊ฐ„๋‹จ ๋‹จ์œ„๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ ๋˜๋„๋ก ํ˜ธ์ถœ ์ฃผ๊ธฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ

  • ๊ตฌํ˜„ ์˜ˆ์‹œ
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);
  };
};
  • scroll ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋‚˜, ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„์— ์‚ฌ์šฉ

  • ๋””๋ฐ”์šด์Šค ๋‚˜ ์Šค๋กœํ‹€์„ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณด๋‹ค๋Š” Underscore ๋‚˜ Lodash ์—์„œ ์ œ๊ณตํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ ํ•จ

๋Œ“๊ธ€