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);
}
};
}