Simple explanation 
What is asked in question?The problem is asking you to create a function cancellable that takes three arguments:1. fn: A function that you want to execute after
# What is asked in question?
---
The problem is asking you to create a function `cancellable` that takes three arguments:

**1. `fn:`** A function that you want to execute after a delay.

**2. `args:`** An array of arguments that you want to pass to the function `fn`.

**3. `t:`** A delay time in milliseconds after which the function `fn` should be executed.

The `cancellable` function should return another function `cancelFn` that, when called, will cancel the execution of `fn` if it hasn't already been executed.

Additionally, there is a `cancelTimeMs` delay that determines when the `cancelFn` function will be invoked. If `cancelFn` is invoked before the delay `t` has passed, the execution of `fn` should be canceled. If `cancelFn` is not invoked within the delay `t`, then `fn` should be executed with the provided `args`.

---

# Example Breakdown

---
**Example 1:**
- `fn = (x) => x * 5`

- `args = [2]`

- `t = 20` (milliseconds)

- `cancelTimeMs = 50` (milliseconds)

In this case:

- The function `fn` is scheduled to execute after 20ms.

- The `cancelFn` is scheduled to be called after 50ms.

- Since 50ms is after 20ms, `fn` will execute at 20ms, and the cancellation will have no effect.

**`Output: [{"time": 20, "returned": 10}]`**

---

**Example 2:**

- `fn = (x) => x**2`

- `args = [2]`

- `t = 100` (milliseconds)

- `cancelTimeMs = 50` (milliseconds)

In this case:

- The function `fn` is scheduled to execute after 100ms.

- The `cancelFn` is scheduled to be called after 50ms.

- Since 50ms is before 100ms, `cancelFn` will be called first, canceling the execution of `fn`.

**`Output: []`**

---


# Code
```javascript []
/**
 * @param {Function} fn
 * @param {Array} args
 * @param {number} t
 * @return {Function}
 */
var cancellable = function(fn, args, t) {
    // Schedule the function fn to be executed after t milliseconds
    const timeoutId = setTimeout(() => {
        fn(...args);
    }, t);

    // Define the cancelFn function
    const cancelFn = () => {
        clearTimeout(timeoutId); // Cancel the execution of fn
    };

    // Return the cancelFn function
    return cancelFn;
};

/**
 *  const result = [];
 *
 *  const fn = (x) => x * 5;
 *  const args = [2], t = 20, cancelTimeMs = 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, cancelTimeMs);
 *           
 *  setTimeout(cancel, cancelTimeMs);
 *
 *  setTimeout(() => {
 *      console.log(result); // [{"time":20,"returned":10}]
 *  }, maxT + 15)
 */
```

---

# Explanation of the Code

---
**1. Scheduling `fn` Execution:**

- We use `setTimeout` to schedule the execution of `fn` after `t` milliseconds. The `setTimeout` function returns a `timeoutId` that we can use to cancel the timeout if needed.

**2. Defining `cancelFn`:**

- The `cancelFn` function uses `clearTimeout(timeoutId)` to cancel the scheduled execution of `fn`. If `cancelFn` is called before `fn` is executed, `fn` will not run.

**3. Returning cancelFn:**

- The `cancellable` function returns `cancelFn`, which can be called later to cancel the execution of `fn`.

**4. Example Usage:**

- In the example, `cancelFn` is scheduled to be called after `cancelTimeMs` (50ms). Depending on the value of `t` and `cancelTimeMs`, `fn` will either execute or be canceled.

This implementation ensures that the function `fn` is only executed if it is not canceled within the specified delay `t`.

---

![upvote.jpg](https://assets.leetcode.com/users/images/aff3220e-a219-4787-ac48-d4d9abdee1c6_1740995340.1806433.jpeg)


['JavaScript']