Hone logo
Hone
Problems

Building a Reusable "UseDebounce" Composable in Vue.js

This challenge focuses on creating a reusable composable function in Vue.js using TypeScript. Composables are a powerful feature allowing you to extract stateful logic and reuse it across multiple components, promoting cleaner and more maintainable code. This challenge will guide you through building a useDebounce composable that delays the execution of a function until after a specified time has elapsed since the last invocation.

Problem Description

You are tasked with creating a Vue.js composable function called useDebounce. This composable should accept a function and a delay (in milliseconds) as arguments. It should return a debounced version of the input function. The debounced function should only be executed after the specified delay has passed without any further calls to the original function.

Key Requirements:

  • Debouncing Logic: The core functionality should debounce the provided function.
  • Delay Parameter: The delay should be configurable and control the debounce time.
  • TypeScript: The composable must be written in TypeScript, ensuring type safety.
  • Reusability: The composable should be easily reusable across different Vue components.
  • Clear API: The composable should have a simple and intuitive API.

Expected Behavior:

When the debounced function is called, a timer is started. If the function is called again within the specified delay, the timer is reset. Only when the delay passes without any further calls is the original function executed.

Edge Cases to Consider:

  • Zero Delay: What should happen if the delay is set to 0? (Consider whether it should execute immediately or not execute at all).
  • Negative Delay: Handle invalid delay values gracefully (e.g., throw an error or default to a reasonable delay).
  • Function Argument: Ensure the function argument is actually a function.
  • Cleanup: Ensure any timers are cleared when the component unmounts to prevent memory leaks.

Examples

Example 1:

Input:
function originalFunction() { console.log("Executing original function"); }
delay = 500

Output:
A debounced function that, when called repeatedly within 500ms, will only execute originalFunction once after 500ms of inactivity.

Explanation:
If originalFunction is called multiple times within 500ms, the timer will be reset each time. Only after 500ms of inactivity will originalFunction be executed.

Example 2:

Input:
function originalFunction(value: string) { console.log("Executing original function with:", value); }
delay = 200

Output:
A debounced function that accepts a string argument and passes it to originalFunction after a 200ms delay.

Explanation:
The debounced function will maintain the latest argument passed to it and pass that argument to originalFunction when it finally executes.

Example 3: (Edge Case)

Input:
function originalFunction() { console.log("Executing original function"); }
delay = 0

Output:
The original function is executed immediately.

Explanation:
A delay of 0 effectively means no debounce, so the function is executed immediately upon the first call.

Constraints

  • Delay Range: The delay value should be a non-negative number. If a negative value is provided, default to a delay of 200ms.
  • Function Type: The first argument to useDebounce must be a function. If it's not, throw a TypeError.
  • Performance: The composable should be efficient and avoid unnecessary re-renders.
  • TypeScript: Strict type checking is expected.

Notes

  • Consider using setTimeout or setInterval to implement the debouncing logic. setTimeout is generally preferred for this use case.
  • Think about how to handle the arguments passed to the original function within the debounced function.
  • Remember to clear the timer when the component unmounts to prevent memory leaks. The onUnmounted lifecycle hook is useful for this.
  • Focus on creating a clean, reusable, and well-typed composable function.
Loading editor...
typescript