Debounce de promesas en JavaScript

JavaScriptJavaScriptBeginner
Practicar Ahora

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

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, exploraremos cómo crear una función anti-rebote que devuelva una promesa en JavaScript. Aprenderemos cómo retrasar la invocación de una función hasta que haya transcurrido un tiempo especificado, y cómo manejar múltiples promesas devueltas durante este tiempo para garantizar que todas devuelvan los mismos datos. Al final de este laboratorio, tendrás una comprensión sólida de cómo implementar el anti-rebote con promesas en tus proyectos de JavaScript.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL javascript(("JavaScript")) -.-> javascript/BasicConceptsGroup(["Basic Concepts"]) javascript(("JavaScript")) -.-> javascript/ToolsandEnvironmentGroup(["Tools and Environment"]) javascript(("JavaScript")) -.-> javascript/AdvancedConceptsGroup(["Advanced Concepts"]) javascript/BasicConceptsGroup -.-> javascript/variables("Variables") javascript/BasicConceptsGroup -.-> javascript/data_types("Data Types") javascript/BasicConceptsGroup -.-> javascript/arith_ops("Arithmetic Operators") javascript/BasicConceptsGroup -.-> javascript/comp_ops("Comparison Operators") javascript/BasicConceptsGroup -.-> javascript/obj_manip("Object Manipulation") javascript/AdvancedConceptsGroup -.-> javascript/async_prog("Asynchronous Programming") javascript/AdvancedConceptsGroup -.-> javascript/destr_assign("Destructuring Assignment") javascript/AdvancedConceptsGroup -.-> javascript/spread_rest("Spread and Rest Operators") javascript/ToolsandEnvironmentGroup -.-> javascript/debugging("Debugging") subgraph Lab Skills javascript/variables -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/data_types -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/arith_ops -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/comp_ops -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/obj_manip -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/async_prog -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/destr_assign -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/spread_rest -.-> lab-28257{{"Debounce de promesas en JavaScript"}} javascript/debugging -.-> lab-28257{{"Debounce de promesas en JavaScript"}} end

Promesa anti-rebote

Para crear una función anti-rebote que devuelva una promesa, retrasando la invocación de la función proporcionada hasta que hayan transcurrido al menos ms milisegundos desde la última vez que se invocó, siga los siguientes pasos:

  1. Cada vez que se invoque la función anti-rebote, quite el temporizador pendiente actual con clearTimeout(), luego use setTimeout() para crear un nuevo temporizador que retrasará la invocación de la función hasta que hayan transcurrido al menos ms milisegundos.
  2. Use Function.prototype.apply() para aplicar el contexto this a la función y proporcionar los argumentos necesarios.
  3. Cree una nueva Promise y agregue sus devoluciones de llamada resolve y reject a la pila de promesas pendientes.
  4. Cuando se llame a setTimeout(), copie la pila actual (ya que puede cambiar entre la llamada a la función proporcionada y su resolución), límpiela y llame a la función proporcionada.
  5. Cuando la función proporcionada se resuelva/rechace, resuelva/rechace todas las promesas en la pila (copiada cuando se llamó a la función) con los datos devueltos.
  6. Omita el segundo argumento, ms, para establecer el temporizador con un valor predeterminado de 0 ms.

A continuación, se muestra el código de la función 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 });
    });
};

A continuación, se muestra un ejemplo de cómo 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);
// Ambos veces mostrará ['resolved', 'bar']

Resumen

¡Felicitaciones! Has completado el laboratorio de Promesa anti-rebote. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.