w3resource

Create Debounced Functions in JavaScript with Promises


Creating a Debounce Function:

Write a JavaScript function that creates a debounce function using Promises and setTimeout.

Solution-1: Using Closures with Promises

Code:

// Function to create a debounced function
function createDebouncedFunction(func, delay) {
  // Hold the timeout reference
  let timeout;

  // Return the debounced function
  return function (...args) {
    // Return a Promise
    return new Promise((resolve) => {
      // Clear any existing timeout
      clearTimeout(timeout);

      // Set a new timeout to delay execution
      timeout = setTimeout(() => {
        // Resolve the Promise with the function execution
        resolve(func(...args));
      }, delay);
    });
  };
}

// Example usage of the debounced function
const debouncedLog = createDebouncedFunction((message) => {
  console.log(message); // Log the message
  return "Message logged";
}, 1000);

// Call the debounced function multiple times
debouncedLog("Hello, World!").then(console.log); // Executes after 1 second
debouncedLog("Hello, JavaScript!").then(console.log); // Cancels previous call

Output:

"Hello, JavaScript!"
"Message logged"

Explanation:

  • createDebouncedFunction(func, delay): Takes a function (func) and a delay in milliseconds as arguments.
  • timeout: Used to store the current setTimeout instance, ensuring only the latest call is executed.
  • clearTimeout(timeout): Cancels any pending timeout.
  • setTimeout: Delays the execution of func until after delay milliseconds.
  • Promise: Wraps the execution, resolving once func is called.
  • Multiple calls reset the timeout, ensuring only the last invocation of debouncedLog is executed.

Solution-2: Using a Class-Based Approach

Code:

// Class to handle debouncing with Promises
class DebouncedFunction {
  constructor(func, delay) {
    this.func = func; // The function to debounce
    this.delay = delay; // The debounce delay
    this.timeout = null; // Store the timeout ID
  }

  // Method to invoke the debounced function
  call(...args) {
    return new Promise((resolve) => {
      // Clear existing timeout
      clearTimeout(this.timeout);

      // Set a new timeout
      this.timeout = setTimeout(() => {
        // Resolve with the function's result
        resolve(this.func(...args));
      }, this.delay);
    });
  }
}

// Example usage of the debounced class
const debouncer = new DebouncedFunction((message) => {
  console.log(message); // Log the message
  return "Message logged";
}, 1500);

// Call the debounced function multiple times
debouncer.call("Message 1").then(console.log); // Executes after 1.5 seconds
debouncer.call("Message 2").then(console.log); // Cancels previous call

Output:

"Message 2"
"Message logged"

Explanation:

  • Class-Based Structure: Encapsulates the debounce logic in a class (DebouncedFunction).
  • this.func and this.delay: Store the function and delay as class properties.
  • this.timeout: Holds the timeout ID.
  • call(...args): Handles the logic for debouncing using promises and setTimeout.
  • Each call clears the previous timeout, ensuring only the latest invocation executes.

See the Pen promises-and-async-await-exercise-13 by w3resource (@w3resource) on CodePen.


Improve this sample solution and post your code through Disqus

Previous: Efficiently Combine Sync and Async tasks with Promise.all.
Next: Using Async/Await with Dynamic imports in JavaScript.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Follow us on Facebook and Twitter for latest update.