DEV Community

Littlee
Littlee

Posted on

setTimeout & setInterval best practice

TL;DR

Use this eslint plugin to enforce the best practice of setTimeout and setInterval.

https://github.com/littlee/eslint-plugin-clean-timer

Motivation

It is always easy to forget to clear the timers set up by setTimeout or setInterval, which can cause bugs that are uneasy to find out.

Image a component with onMount and onUnmount life cycles, in the code below, if the component is mounted and unmounted within 1000ms, the timer will still fire.

class App {
  onMout() {
    setInterval(() => {
      /* do somthing */
    }, 1000);
  }
}
Enter fullscreen mode Exit fullscreen mode

The best practice is to clear the timer whenever we don't need it anymore.

class App {
  onMout() {
    this.timer = setInterval(() => {
      /* do somthing */
    }, 1000);
  }
  onUnmount() {
    clearInterval(this.timer);
  }
}
Enter fullscreen mode Exit fullscreen mode

But, so many times I'm likely to forget to clear this timer until I find it causes a bug in runtime.

So I've created an eslint plugin to remind me to clear the timers before I run the code.

I call this plugin eslint-plugin-clean-timer since it can make our timer-code clean.

github repo: https://github.com/littlee/eslint-plugin-clean-timer

It's easy to set up this plugin in our project.

First, install it with npm

npm i -D eslint-plugin-clean-timer
Enter fullscreen mode Exit fullscreen mode

Second, add clean-timer in eslint configuration

{
  "plugins": ["clean-timer"],
  "rules": {
    "clean-timer/assign-timer-id": 2
  }
}
Enter fullscreen mode Exit fullscreen mode

And we're done.

Now every time we set up a timer without assigning the return value to a variable or a member, eslint will complain about it. (The only exception is when using setTimeout without a delay value, like setTimeout(() => {}) or setTimeout(() => {}, 0))

Also, if we're using VSCode with ESLint extension installed, we can use the "Quick Fix..." feature to insert the timer id assign statement automatically, and then change the timer identifier to any name we like.

Screen Cast

Top comments (0)