Mark As Completed Discussion

Good afternoon! Here's our prompt for today.

Mastering Time Control in Browsers with window.clearAllTimeouts

Imagine you have the power to control time in your browser. You can schedule events to happen in the future and even cancel them before they occur. This is exactly what window.setTimeout() and window.clearTimeout() allow you to do!

Scheduling a Future Event with setTimeout

Let's say you want to display a message that pops up after 5 seconds. You can do this by scheduling a function to run at a future time using window.setTimeout(). Here's how it's done:

JAVASCRIPT
1const alertInFive = () => {
2  window.alert("This will show up after 5 seconds!");
3};
4
5const newTimeout = setTimeout(alertInFive, 5000);

Canceling a Scheduled Event with clearTimeout

What if you have second thoughts and decide you don't want that message to pop up? No worries, you can cancel the scheduled function using window.clearTimeout().

JAVASCRIPT
1const newTimeout = setTimeout(alertInFive, 5000);
2window.clearTimeout(newTimeout);

A New Challenge: Clearing All Timeouts

Now, let's level up. What if you have multiple functions scheduled and you want to cancel them all? Your mission, should you choose to accept it, is to create a function called window.clearAllTimeouts().

When invoked, this function will clear every timeout on the page. Here's what the usage would look like:

JAVASCRIPT
1setTimeout(func1, 500);
2setTimeout(func2, 500);
3setTimeout(func3, 500);
4setTimeout(func4, 500);
5
6window.clearAllTimeouts();
7// No scheduled functions run!

Question

Your task is to write this utility function. It's like being a time-controlling superhero for your browser! Are you up for the challenge?

Try to solve this here or in Interactive Mode.

How do I practice this challenge?

JAVASCRIPT
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Here's how we would solve this problem...

How do I use this guide?

Keeping Track of Timers

The primary challenge here is how to maintain a list of all active timers in the window object. Our aim is to be able to loop through this list and cancel each timer using window.clearTimeout.

Utilizing Sets for Efficient Tracking

We'll use a Set, aptly named timers, to hold timer IDs. Sets are a data structure that allow us to enjoy near-constant time for both insertion and deletion.

JAVASCRIPT
1const timers = new Set();

Storing Native Functions

Before we create custom wrapper functions around window.setTimeout and window.clearTimeout, it's essential to save the native implementations. We'll store these in variables named window.nativeSetTimeout and window.nativeClearTimeout.

JAVASCRIPT
1const timers = new Set();
2window.nativeSetTimeout = window.setTimeout;
3window.nativeClearTimeout = window.clearTimeout;

Crafting Wrapper Functions for Timer Management

Now let's get creative! We can write custom wrapper functions around window.setTimeout and window.clearTimeout. These wrappers will have an additional duty: tracking new timers. When a new timer is created, its ID will be added to our Set. Similarly, we'll remove IDs when timers are cleared or completed.

JAVASCRIPT
1window.setTimeout = (cb, time, ...args) => {
2  const cbWrapper = () => {
3    cb(...args);
4    // No longer need to track once completed
5    timers.delete(id);
6  };
7  const id = window.nativeSetTimeout(cbWrapper, time);
8  timers.add(id);
9  return id;
10};
11
12window.clearTimeout = (id) => {
13  window.nativeClearTimeout(id);
14  timers.delete(id);
15};

In these wrapper functions, we use the native implementations to actually set and clear the timeouts. Our added functionality is simply to manage the timer IDs using the timers Set. This way, when you need to clear all timeouts, you can easily loop through this Set and clear each one.

Implementing the Clear-All Mechanism

Now that we've got a way to keep track of all active timers, implementing the clearAllTimeouts function becomes a straightforward task.

Leveraging the Set for Mass Cancellation

The core idea is to simply loop through our timers Set and use the native clearTimeout function on each timer ID stored in it. This will effectively stop all the timers, and your window will be free from any lingering timing events.

JAVASCRIPT
1const timers = new Set();
2window.nativeSetTimeout = window.setTimeout;
3window.nativeClearTimeout = window.clearTimeout;
4
5// The magic happens here
6window.clearAllTimeouts = () => {
7  for (const id of timers) {
8    window.clearTimeout(id);
9  }
10};
11
12window.setTimeout = (cb, time, ...args) => {
13  const cbWrapper = () => {
14    cb(...args);
15    // No more tracking needed
16    timers.delete(id);
17  };
18  const id = window.nativeSetTimeout(cbWrapper, time);
19  timers.add(id);
20  return id;
21};
22
23window.clearTimeout = (id) => {
24  window.nativeClearTimeout(id);
25  timers.delete(id);
26};

In this setup, the clearAllTimeouts function leverages the existing timers Set to halt all the active timers. Since we've been diligent in tracking every new timer and removing each one that gets cleared or completed, this Set will always be current. As a result, clearAllTimeouts becomes a powerful tool to halt all timers with a single call.

One Pager Cheat Sheet

  • With window.setTimeout() and window.clearTimeout(), you can schedule and clear timeouts, respectively, but can you write a method, window.clearAllTimeouts, to clear multiple timeouts at once?
  • We have overwritten the native window.setTimeout and window.clearTimeout functions to add and remove timer IDs to/from a Set collection, in order to implement a custom clearAllTimeouts function.
  • ClearAllTimeouts iterates through each timer and manually clears it.

This is our final solution.

To visualize the solution and step through the below code, click Visualize the Solution on the right-side menu or the VISUALIZE button in Interactive Mode.

JAVASCRIPT
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

You're doing a wonderful job. Keep going!

If you had any problems with this tutorial, check out the main forum thread here.