Debounce Promises em JavaScript

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Neste laboratório, exploraremos como criar uma função debounced (com debounce) que retorna uma promise em JavaScript. Aprenderemos como atrasar a invocação de uma função até que um tempo especificado tenha decorrido e como lidar com múltiplas promises retornadas durante esse tempo para garantir que todas retornem os mesmos dados. Ao final deste laboratório, você terá uma sólida compreensão de como implementar debouncing com promises em seus projetos JavaScript.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível iniciante com uma taxa de conclusão de 100%. Recebeu uma taxa de avaliações positivas de 100% dos estudantes.

Debounce Promise (Promise com Debounce)

Para criar uma função debounced (com debounce) que retorna uma promise, atrasando a invocação da função fornecida até que pelo menos ms milissegundos tenham decorrido desde a última vez que foi invocada, use as seguintes etapas:

  1. Toda vez que a função debounced é invocada, limpe o timeout pendente atual com clearTimeout(), então use setTimeout() para criar um novo timeout que atrasa a invocação da função até que pelo menos ms milissegundos tenham decorrido.
  2. Use Function.prototype.apply() para aplicar o contexto this à função e fornecer os argumentos necessários.
  3. Crie uma nova Promise e adicione seus callbacks resolve e reject à pilha de promises pending.
  4. Quando setTimeout() é chamado, copie a pilha atual (pois ela pode mudar entre a chamada da função fornecida e sua resolução), limpe-a e chame a função fornecida.
  5. Quando a função fornecida resolve/rejeita, resolva/rejeite todas as promises na pilha (copiada quando a função foi chamada) com os dados retornados.
  6. Omita o segundo argumento, ms, para definir o timeout em um padrão de 0 ms.

Aqui está o código para a função debouncePromise():

const debouncePromise = (fn, ms = 0) => {
  let timeoutId;
  const pending = [];
  return (...args) =>
    new Promise((res, rej) => {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        const currentPending = [...pending];
        pending.length = 0;
        Promise.resolve(fn.apply(this, args)).then(
          (data) => {
            currentPending.forEach(({ resolve }) => resolve(data));
          },
          (error) => {
            currentPending.forEach(({ reject }) => reject(error));
          }
        );
      }, ms);
      pending.push({ resolve: res, reject: rej });
    });
};

Aqui está um exemplo de como usar debouncePromise():

const fn = (arg) =>
  new Promise((resolve) => {
    setTimeout(resolve, 1000, ["resolved", arg]);
  });
const debounced = debouncePromise(fn, 200);
debounced("foo").then(console.log);
debounced("bar").then(console.log);
// Will log ['resolved', 'bar'] both times

Resumo

Parabéns! Você concluiu o laboratório Debounce Promise. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.