Timeout Cancellation

Updated on 15 July, 2025
Timeout Cancellation header image

Problem Statement

The task involves creating a mechanism in programming where a function fn provided by the user is scheduled to be executed after a delay t measured in milliseconds. Alongside, the function also provides a cancelFn, which when called within the time t, prevents the execution of fn. If the cancellation is not enacted within the specified time, the function fn automatically executes with the provided arguments args. The environment also includes a parameter cancelTimeMs, which indicates when cancelFn will be executed automatically if not manually triggered earlier.

Examples

Example 1

Input:

fn = (x) => x * 5, args = [2], t = 20

Output:

[{"time": 20, "returned": 10}]

Explanation:

const cancelTimeMs = 50;
const cancelFn = cancellable((x) => x * 5, [2], 20);
setTimeout(cancelFn, cancelTimeMs);
The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), which happened after the execution of fn(2) at 20ms.

Example 2

Input:

fn = (x) => x**2, args = [2], t = 100

Output:

[]

Explanation:

const cancelTimeMs = 50;
const cancelFn = cancellable((x) => x**2, [2], 100);
setTimeout(cancelFn, cancelTimeMs);
The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), which happened before the execution of fn(2) at 100ms, resulting in fn(2) never being called.

Example 3

Input:

fn = (x1, x2) => x1 * x2, args = [2,4], t = 30

Output:

[{"time": 30, "returned": 8}]

Explanation:

const cancelTimeMs = 100;
const cancelFn = cancellable((x1, x2) => x1 * x2, [2,4], 30);
setTimeout(cancelFn, cancelTimeMs);
The cancellation was scheduled to occur after a delay of cancelTimeMs (100ms), which happened after the execution of fn(2,4) at 30ms.

Constraints

  • fn is a function
  • args is a valid JSON array
  • 1 <= args.length <= 10
  • 20 <= t <= 1000
  • 10 <= cancelTimeMs <= 1000

Approach and Intuition

  1. Framework Setup:

    • Begin by scheduling the main function fn to execute after a delay of t milliseconds using setTimeout.
    • Provide a cancellation function cancelFn that can be called manually anytime within this delay to stop the execution of fn.
  2. Cancellation Logic:

    • Implement cancelFn such that it clears the scheduled execution of fn. This requires maintaining a reference to the timer set by setTimeout.
  3. Automatic Cancellation Setup:

    • Schedule cancelFn for automatic execution after cancelTimeMs milliseconds using another setTimeout.
    • If cancelFn is executed (either manually or automatically) before fn’s scheduled execution, it should prevent fn from executing.
  4. Execution Conditionally Based on Time:

    • If neither manual nor automatic cancellation happens before time t, fn will execute with args.
  5. Return the Necessary Handlers:

    • The function should return cancelFn so that it can be invoked manually if needed.

Understanding the Examples:

  • In the scenarios given, whether fn executes depends on whether cancelFn is triggered before time t either manually or automatically. The decision and the order of timings (whether t is less than or greater than cancelTimeMs) dictate if fn gets called.
  • For instance, in an example where t is 20ms and cancelTimeMs is 50ms, the cancellation attempt occurs after the function execution, thus fn executes unaffected. Conversely, if cancelTimeMs is 50ms and t is 100ms, the cancellation is triggered before fn could run, leading to it never being executed.

This approach hinges on the precise coordination of JavaScript's asynchronous setTimeout function and involves managing the lifecycle of timers effectively to enforce the desired behaviour of conditional execution based on time and user intervention.

Solutions

  • JavaScript
js
var deferrableExecution = function(callback, parameters, delay) {
  let cancelled = false;
  setTimeout(() => {
      if (!cancelled)
          callback(...parameters);
  }, delay);
    
  return () => {
    cancelled = true;
  };
};

This JavaScript function, deferrableExecution, manages time-sensitive operations with the ability to cancel them as needed. Utilize this function when a delayed action may need interruption before its execution. Here’s a concise exploration of its functionality and usage:

  • Define deferrableExecution which takes three parameters:

    • callback: The function to execute after a delay.
    • parameters: Arguments to pass to the callback function.
    • delay: Time in milliseconds before the callback is executed.
  • Within the function, initiate a variable cancelled set to false. This flag helps in managing whether the scheduled operation should proceed.

  • Use setTimeout to delay the callback execution. Inside the timeout function, check if cancelled remains false. If true, execute the callback with the provided parameters using the spread syntax ...parameters.

  • Return an anonymous function from deferrableExecution. Calling this returned function sets cancelled to true, effectively cancelling the scheduled callback if invoked before the delay expires.

Integrate deferrableExecution into your codebase where conditional or cancellable delays are necessary, enhancing control over asynchronous operations.

Comments

No comments yet.