Talentd
FleetCode
Make and follow sheets.Sign in

Timeout Cancellation solution and explanation

Easy5 min read89.1% acceptanceUpdated 9 Apr 2026
Timeout Cancellation | Leetcode 2715 | Promises and Time | 30 Days of JavaScript #javascriptLearn With Chirag · 11:55 · 3K viewsWatch on YouTube
9 more videos on this problem
  1. Timeout Cancellation | Leetcode 2715 | Promises and Time | 30 Days of JavaScript #javascriptLearn With Chirag · 11:55 · 3K views
  2. #day14 |2715 Timeout Cancellation| 30 Days of Javascript | Leetcode-2715| clearTimeout() |Time in JSCoding with Ankita · 9:58 · 1K views
  3. Leetcode - Timeout CancellationVinhNuwin · 3:37 · 902 views
  4. #Leetcode 2715 Timeout Cancellation 🚀 Day 14 👨‍💻 30Days of JavaScript Challenge LeetCodeRajat Talesra · 5:25 · 327 views
  5. Timeout Cancellation - 2715 Leetcode Problem - 30 Days of JavaScriptanalyse_code_test · 3:32 · 134 views
  6. LeetCode | 2715. Timeout Cancellation | 30 Days of Javascript | 中文解說Harry謝 · 5:33 · 80 views
  7. 2715. Timeout Cancellation | Day 14 – How to Cancel a Scheduled Function in JavaScriptCodeCrafting with Vishnu · 4:23 · 69 views
  8. 30 days of JavaScript - Timeout CancellationCode With Bertrand · 16:35 · 55 views
  9. 2715 Timeout CancellationmanjeetVlogs · 2:20 · 28 views
  10. #2715 Timeout Cancellation | 30 Days of JavaScript | Programmers Choice #javascript #leetcode #jsProgrammers choice · 7:28 · 26 views

The problem

Given a function fn, an array of arguments args, and a timeout t in milliseconds, return a cancel function cancelFn.

After a delay of cancelTimeMs, the returned cancel function cancelFn will be invoked.

setTimeout(cancelFn, cancelTimeMs)

Initially, the execution of the function fn should be delayed by t milliseconds.

If, before the delay of t milliseconds, the function cancelFn is invoked, it should cancel the delayed execution of fn. Otherwise, if cancelFn is not invoked within the specified delay t, fn should be executed with the provided args as arguments.

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 overview

Problem Overview: You need to schedule a function fn to run after t milliseconds and return another function that cancels the scheduled execution. If the cancel function runs before the timer fires, fn must never execute. This problem checks your understanding of timer APIs and basic asynchronous programming.

Approach 1: Using setTimeout and clearTimeout (O(1) time, O(1) space)

The direct solution schedules the callback using setTimeout and stores the returned timer identifier. JavaScript timers return an ID that uniquely represents the scheduled task. The cancellation function simply calls clearTimeout(timerId), which removes the scheduled callback from the event loop queue before it executes.

The key insight is that timer scheduling and cancellation are constant‑time operations managed by the runtime. No iteration or extra data structures are required. When the cancel function executes before the delay expires, the timer is invalidated and the callback never runs. If the timer already fired, calling clearTimeout has no effect.

This approach mirrors how real systems manage scheduled tasks. Most interviewers expect you to know the relationship between setTimeout and clearTimeout and how the event loop handles deferred execution in JavaScript.

Approach 2: Using Promises for Asynchronous Control (O(1) time, O(1) space)

Another implementation wraps the delayed execution inside a Promise. A timer triggers the promise resolution after t milliseconds, which then executes the callback. The cancellation function prevents the resolution by clearing the timer or toggling a flag that stops the callback from running.

This design is useful when your codebase already relies heavily on promises or async workflows. For example, a promise-based wrapper can integrate with async/await, cancellation tokens, or higher-level task management systems. The runtime cost remains constant because only one timer and one promise object are created.

While slightly more abstract, this version demonstrates how timers can coordinate with Promises to control asynchronous flow. The core mechanism still relies on canceling the scheduled timeout before execution.

Recommended for interviews: The setTimeout + clearTimeout approach is the expected solution. It shows you understand how timers work in the event loop and how scheduled callbacks can be canceled. The promise-based version is useful for system design discussions or async-heavy applications, but the direct timer cancellation approach is clearer and closer to how the runtime APIs are designed.

Approach 1: Using setTimeout and clearTimeout

This approach leverages JavaScript's built-in setTimeout and clearTimeout functions. We schedule a timeout to execute the function fn after t milliseconds, and we return a cancelFn that, when called, cancels this scheduled timeout.

import threading

class TimeoutFunction:
    def __init__(self, fn, t):
        self.fn = fn
        self.t = t
        self.timer = None

    def start(self):
        self.timer = threading.Timer(self.t / 1000, self.fn)
        self.timer.start()

    def cancel(self):
        if self.timer:
            self.timer.cancel()

# Example usage
fn = lambda: print(10)
timeout_fn = TimeoutFunction(fn, 20)
timeout_fn.start()

# Simulate cancel call
timeout_fn.cancel()  # Should cancel the execution
import java.util.Timer;
import java.util.TimerTask;

public class TimeoutFunction {
    public static Runnable cancellable(Runnable fn, int t) {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                fn.run();
                timer.cancel();
            }
        };
        timer.schedule(task, t);

        return () -> {
            task.cancel();
            timer.cancel();
        };
    }

    public static void main(String[] args) {
        Runnable fn = () -> System.out.println(10);
        Runnable cancelFn = cancellable(fn, 20);

        // Simulate cancel call
delayCall(10, cancelFn);  // Should cancel the execution
    }

    private static void delayCall(int delay, Runnable callback) {
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                callback.run();
            }
        }, delay);
    }
}
/* Similar to C, C++ requires external libraries or platform-specific APIs for handling async behavior akin to JavaScript setTimeout. Common solutions involve threads or async libraries. */
function cancellable(fn, args, t) {
  let timeoutId = setTimeout(() => {
    fn(...args);
  }, t);
  
  return () => clearTimeout(timeoutId);
}

// Example usage
const fn = (x) => console.log(x * 5);
const cancelFn = cancellable(fn, [2], 20);

// Simulate cancel call
setTimeout(cancelFn, 10);  // Should cancel the execution
/* In C, we typically don't use timeouts like JavaScript. However, if you're using a multi-threaded program, you can achieve similar behavior with thread sleeping and cancellation. C standard library does not provide portable setTimeout/clearTimeout functions. */
using System;
using System.Threading;

public class TimeoutFunction
{
    private Timer _timer;

    public TimeoutFunction(Action fn, int t)
    {
        _timer = new Timer(_ => fn(), null, t, Timeout.Infinite);
    }

    public void Cancel()
    {
        _timer?.Dispose();
    }
}

// Example usage
public class Program
{
    public static void Main()
    {
        Action fn = () => Console.WriteLine(10);
        TimeoutFunction timeoutFunction = new TimeoutFunction(fn, 20);

        // Simulate cancel call
        timeoutFunction.Cancel();
    }
}

Python provides the threading module, which includes a Timer class to achieve similar functionality as setTimeout. We define a class TimeoutFunction to encapsulate the function and timeout behavior, with start and cancel methods for execution control.

Complexity

Time Complexity: O(1) since we're creating and deleting a single thread.
Space Complexity: O(1) as we're maintaining minimal state within the class instance.

Try this approach in the editor

Approach 2: Using Promises for Asynchronous Control

This alternative approach involves using Promises to manage asynchronous execution and potential cancelation. By wrapping the setTimeout within a Promise, we can have more control over its execution and cancelation by managing the Promise lifecycle.

import asyncio

async def cancellable(fn, args, t):
    task = asyncio.ensure_future(asyncio.sleep(t / 1000))

    async def cancel_task():
        if not task.done():
            task.cancel()
            print("Cancelled")

    try:
        await task
        fn(*args)
    except asyncio.CancelledError:
        pass
    return cancel_task

async def main():
    async def myFunction(x):
        print(x * 5)

    cancel_fn = await cancellable(myFunction, [2], 20)

    # Simulate cancel call
    await asyncio.sleep(0.01)  # Less than 20ms, hence should cancel the execution
    await cancel_fn()

asyncio.run(main())
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class PromiseTimeout {
    public static CompletableFuture<Void> cancellable(Runnable fn, int t) {
        CompletableFuture<Void> promise = new CompletableFuture<>();

        ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(1);

        scheduledExecutor.schedule(() -> {
            if (!promise.isDone()) {
                fn.run();
                promise.complete(null);
            }
        }, t, TimeUnit.MILLISECONDS);

        return promise;   // Caller should complete this promise to cancel
    }

    public static void main(String[] args) throws Exception {
        Runnable fn = () -> System.out.println(10);
        CompletableFuture<Void> future = cancellable(fn, 500);

        // Simulate cancel call after 200 ms
        Thread.sleep(200);
        future.complete(null);  // Cancels the execution of fn if not already done
    }
}
/* Again, in C++, achieving a Promise-like handling for timeouts requires either using the C++ Standard Library's future and promise features, or a third-party async library. *
function cancellableWithPromise(fn, args, t) {
  let cancelFn;

  const promise = new Promise((resolve) => {
    const timeoutId = setTimeout(() => {
      resolve(fn(...args));
    }, t);

    cancelFn = () => {
      clearTimeout(timeoutId);
      resolve('Cancelled');
    };
  });

  return { promise, cancelFn };
}

// Example usage
const fn = (x) => console.log(x * 5);
const { promise, cancelFn } = cancellableWithPromise(fn, [2], 20);

// Simulate cancel call
setTimeout(() => {
  cancelFn();
  promise.then((result) => console.log(result));
}, 10);
/* In C, you might implement this using threads and synchronizations like semaphores or condition variables to emulate Promise-like async tasks. Normally, C programs would not use this style directly. */
using System;
using System.Threading;
using System.Threading.Tasks;

public class PromiseTimeout
{
    public static async Task<Func<Task>> Cancellable(Action fn, int t)
    {
        var cts = new CancellationTokenSource();

        Task.Delay(t, cts.Token).ContinueWith(_ =>
        {
            if (!cts.Token.IsCancellationRequested)
            {
                fn();
            }
        }, TaskScheduler.Current);

        return async () => 
        {
            cts.Cancel();
            await Task.CompletedTask;
        };
    }

    public static async Task Main(string[] args)
    {
        Action fn = () => Console.WriteLine(10);
        var cancel = await Cancellable(fn, 2000); // Trying with a delay-longer-than-task to show cancellation

        // Simulate cancel call
        Thread.Sleep(1000); // Less than 2000ms, hence should cancel
        await cancel();
    }
}

Python's asyncio library is employed to establish async tasks similar to Promises. We define an asynchronous cancellable function to handle the timeout and a separate task for cancelation, leveraging the async/await syntax.

Complexity

Time Complexity: O(1) per async operation including scheduling and canceling.
Space Complexity: O(1) for maintaining task references.

Try this approach in the editor

Approach 3: Default Approach

function cancellable(fn: Function, args: any[], t: number): Function {
    const timer = setTimeout(() => fn(...args), t);
    return () => {
        clearTimeout(timer);
    };
}

/**
 *  const result = []
 *
 *  const fn = (x) => x * 5
 *  const args = [2], t = 20, cancelT = 50
 *
 *  const start = performance.now()
 *
 *  const log = (...argsArr) => {
 *      const diff = Math.floor(performance.now() - start);
 *      result.push({"time": diff, "returned": fn(...argsArr))
 *  }
 *
 *  const cancel = cancellable(log, args, t);
 *
 *  const maxT = Math.max(t, cancelT)
 *
 *  setTimeout(() => {
 *     cancel()
 *  }, cancelT)
 *
 *  setTimeout(() => {
 *     console.log(result) // [{"time":20,"returned":10}]
 *  }, maxT + 15)
 */
Try this approach in the editor

Complexity comparison

ApproachComplexity
Using setTimeout and clearTimeout

Time Complexity: O(1) since we're creating and deleting a single thread.
Space Complexity: O(1) as we're maintaining minimal state within the class instance.

Using Promises for Asynchronous Control

Time Complexity: O(1) per async operation including scheduling and canceling.
Space Complexity: O(1) for maintaining task references.

Default Approach–

Complexity analysis

ApproachTimeSpaceWhen to Use
Using setTimeout and clearTimeoutO(1)O(1)Standard solution when working directly with timers or event loop scheduling
Using Promises for Asynchronous ControlO(1)O(1)When integrating timer logic into promise-based or async/await workflows

Frequently asked questions

Is Timeout Cancellation easy or hard?

Timeout Cancellation is considered an Easy problem. The main concept is understanding how scheduled callbacks work and how to cancel them before execution using a timer identifier.

Timeout Cancellation Python/Java solution

In JavaScript the solution uses setTimeout and clearTimeout directly. In languages like Python or Java, similar behavior can be implemented using scheduling utilities such as threading timers, scheduled executors, or async task handlers that support cancellation.

How to solve Timeout Cancellation in O(1)?

Store the timer ID returned from setTimeout when scheduling the callback. Return a function that calls clearTimeout(timerId). Because timer operations are handled internally by the runtime event loop, both scheduling and cancellation execute in constant time.

What is the best approach for Timeout Cancellation?

The most straightforward approach uses setTimeout to schedule the callback and clearTimeout to cancel it. The timer ID returned by setTimeout is stored and passed to clearTimeout inside the cancel function. Both scheduling and cancellation run in O(1) time and require O(1) space.

Is Timeout Cancellation asked at Google/Amazon/Meta?

Timeout and asynchronous control questions appear in frontend and JavaScript-focused interviews at companies like Google, Amazon, and Meta. While this exact problem may vary, understanding timers, event loops, and cancellation patterns is commonly tested.

What data structure is used in Timeout Cancellation?

No explicit data structure is required. The solution relies on the runtime timer system where setTimeout returns a numeric or object-based timer ID that can be passed to clearTimeout for cancellation.

What is the time complexity of Timeout Cancellation?

Timeout scheduling and cancellation both run in constant time. Creating the timer with setTimeout is O(1), and canceling it using clearTimeout is also O(1). The solution does not depend on input size and uses constant memory.

Comments

Now write it yourselfClose this page and solve Timeout Cancellation in the editor, without looking.
Practise Timeout Cancellation