Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to clear all timeouts and intervals? #174

Closed
vsemozhetbyt opened this issue May 22, 2016 · 10 comments
Closed

Is there a way to clear all timeouts and intervals? #174

vsemozhetbyt opened this issue May 22, 2016 · 10 comments

Comments

@vsemozhetbyt
Copy link

vsemozhetbyt commented May 22, 2016

In the browser context window.setTimeout and window.setInterval return an integer, so users can clean up like this (test this code in the browser console or source snippets):

window.setTimeout(() => {console.log('Timeout');}, 500);
window.setInterval(() => {console.log('Interval');}, 1000);

let id = window.setTimeout(() => {}, 0);
console.log(id);
while (id) {
  window.clearTimeout(id);
  id--;
}

id = window.setInterval(() => {}, 0);
console.log(id);
while (id) {
  window.clearInterval(id);
  id--;
}

In Node.js timers return an object with no exposed properties or methods, except ref and unref. Is there still a way to clear all timers and intervals in Node.js?

@vsemozhetbyt vsemozhetbyt changed the title Is there a way to clear all timers and intervals? Is there a way to clear all timeouts and intervals? May 23, 2016
@SomeoneWeird
Copy link
Member

Not as far as I'm aware. I'd probably wrap setInterval and setTimeout in another function that pushes the ids into an array, to keep track of them.

@vsemozhetbyt
Copy link
Author

vsemozhetbyt commented May 24, 2016

Yes, this is a solution for timers under control and track. But what if I need to clean up, say, after some incautious and intricate module?

@Knighton910
Copy link
Contributor

did you have success with this problem @vsemozhetbyt

@vsemozhetbyt
Copy link
Author

Theoretically no, but I've found a workaround for a particular case. If there is no way to resolve this in general, well, the issue could be closed, I think.

@bcherny
Copy link

bcherny commented Oct 31, 2016

Something like this hack works pretty well for browser envs, but since Timers don't expose IDs in Node, I haven't found a way to cancel all timers in Node.

My use case is I'm running a 3rd party script, and for some reason even when that script returned, my process kept running. Using why-is-node-running I saw that the 3rd party script set a few timeouts, which prevented my script from exiting.

I'd rather not use process.exit since my script is consumed by other scripts, which manage their own process. It seems like there are a few workarounds:

  1. Wrap setTimeout to register timeouts in a global registry before I invoke the 3rd party script
  2. Run the 3rd party script in its own child process, which my process can then kill

Neither of these are pretty. It would be fantastic to have a better way to do this.

@Fishrock123
Copy link
Member

If you'd like this, could you open a feature request on https://github.com/nodejs/node? Thanks!

@burtonator
Copy link

WebserverTest is also something that refuses to shut down...

@burtonator
Copy link

CacheEntriesFactoryTest refuses to shut down due to the CachingPHZReader setting a timeout of 1m

constructor(path: string, timeout: number = 60000)

@xgqfrms
Copy link

xgqfrms commented Jul 27, 2020

clearAllSetTimeouts

ES6 solution

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2020-07-27
 * @modified
 *
 * @description clearAllSetTimeouts
 * @difficulty Easy Medium Hard
 * @complexity O(n)
 * @augments
 * @example
 * @link
 * @solutions
 *
 */

const log = console.log;

class clearAllSetTimeouts {
  constructor(name) {
    this.name = name;
  }
  static ids = [];
  static add(callback, timeout) {
    const id = setTimeout(() => {
      callback();
    }, timeout);
    log(`add id`, id);
    this.ids.push(id);
  }
  static clearAll() {
    const arr = this.ids;
    let len = this.ids.length;
    while (len > 0) {
      const id = arr[len - 1];
      log(`clear id`, id);
      clearTimeout(id);
      len--;
    }
  }
};

// test
clearAllSetTimeouts.add(() => log(`1`), 0)
clearAllSetTimeouts.add(() => log(`2`), 0)
clearAllSetTimeouts.add(() => log(`3`), 0)

clearAllSetTimeouts.clearAll();

image

@ashishsiddhu
Copy link

When you set an interval, you get a pointer to it.
To clear all intervals, you'll need to store all of them:

var arr = [];
arr.push(setInterval(function () {
    console.log(1);
  }, 1000));
arr.push(setInterval(function () {
    console.log(2);
  }, 1000));
arr.push(setInterval(function () {
    console.log(3);
  }, 1000));

Following loop will clear all intervals

// Clear multiple Intervals
  arr.map((a) => {
    console.log(a)
    clearInterval(a);
    arr = [];
  })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants