Debounce e Throttle: Implementações para Controle de Eventos

Definições

  • Throttle: Executa a função apenas uma vez a cada intervalo de n segundos; chamadas adicionais dentro desse período são ignoradas.
  • Debounce: Adia a execução da função até n segundos após a última chamada; reinicia o temporizador se houver nova ativação dentro do intervalo.

Debounce

Implementação Básica


function criarDebounce(funcaoAtrasada, intervalo) {
  let identificadorTimer = null;
  return function (...parametros) {
    const contextoExecucao = this;
    clearTimeout(identificadorTimer);
    identificadorTimer = setTimeout(() => {
      funcaoAtrasada.apply(contextoExecucao, parametros);
    }, intervalo);
  };
}

Implementação com Execução Imediata


function debounceExecucaoImediata(funcaoAtrasada, intervalo, iniciarImediatamente) {
  let identificadorTimer;
  return function () {
    const contextoExecucao = this;
    const parametros = arguments;
    const executarAgora = iniciarImediatamente && !identificadorTimer;
    clearTimeout(identificadorTimer);
    identificadorTimer = setTimeout(() => {
      identificadorTimer = null;
      if (!iniciarImediatamente) {
        funcaoAtrasada.apply(contextoExecucao, parametros);
      }
    }, intervalo);
    if (executarAgora) {
      funcaoAtrasada.apply(contextoExecucao, parametros);
    }
  };
}

Throttle

Existem múltiplas técnicas para implementar throttle, incluindo abordagens baseadas em timestamps e em temporizadores.

Abodragem com Timestamp

Executa imediatamente na primeira ativação, mas não re-executa após o término do gatilho.


function throttlePorTimestamp(funcaoLimitada, atraso = 500) {
  let tempoAnterior = Date.now();
  return function (...argumentos) {
    const tempoAtual = Date.now();
    if (tempoAtual - tempoAnterior >= atraso) {
      funcaoLimitada.apply(null, argumentos);
      tempoAnterior = tempoAtual;
    }
  };
}

Abordagem com Temporizador

Atrasa a primeira execução em 'atraso' milissegundos e garante uma execução final após o gatilho parar.


function throttlePorTemporizador(funcaoLimitada, atraso = 500) {
  let identificadorTimer = null;
  return function (...argumentos) {
    if (!identificadorTimer) {
      identificadorTimer = setTimeout(() => {
        funcaoLimitada.apply(this, argumentos);
        identificadorTimer = null;
      }, atraso);
    }
  };
}

Implementação Híbrida

Combina as vantagens de ambas as técnicas para um controle mais preciso da taxa de execução.


function throttleHibrido(funcaoLimitada, atraso) {
  let identificadorTimer = null;
  let inicioContagem = Date.now();
  return function () {
    const tempoAtual = Date.now();
    const tempoRestante = atraso - (tempoAtual - inicioContagem);
    const contextoExecucao = this;
    const argumentos = arguments;
    clearTimeout(identificadorTimer);
    if (tempoRestante <= 0) {
      funcaoLimitada.apply(contextoExecucao, argumentos);
      inicioContagem = tempoAtual;
    } else {
      identificadorTimer = setTimeout(() => {
        funcaoLimitada.apply(contextoExecucao, argumentos);
      }, tempoRestante);
    }
  };
}

Tags: javascript debounce Throttle EventHandling FrontendDevelopment

Publicado em 7-14 18:09