How to stop setinterval from another function

Viewed 175

I have two functions within my background.js. First function starts a counter, the second clears it from local storage. The problem is the setInterval in the first function keeps on running even after the second function is triggered. How can I clear a setinterval from another function?

background.js


function startTimelapsFunction() {
if (!localStorage.getItem('startTime')) {
  localStorage.setItem('startTime', Date.now());
}

const startTime = parseInt(localStorage.getItem('startTime'), 10);

const writeTime = () => {
  console.log('startTime', startTime)
  const currentTime = Date.now();
  console.log('currentTime', currentTime)
  const secondsDiff = Math.floor((currentTime - startTime) / 1000);
  console.log('secondsDiff', secondsDiff)
  document.body.innerText = secondsDiff;
  localStorage.setItem('myCat', secondsDiff);
};
setInterval(writeTime, 1000);
writeTime();
}



function resetTimelapsFunction() {
  localStorage.removeItem("myCat");
  localStorage.removeItem("startTime");
}

4 Answers

you need to keep the intervalId returned by the setInterval function and call a clearInterval(intervalId) in your second function (take a look here). For example:

let intervalId = null;

function startTimelapsFunction() {
 if (!localStorage.getItem('startTime')) {
   localStorage.setItem('startTime', Date.now());
 }

 const startTime = parseInt(localStorage.getItem('startTime'), 10);

 const writeTime = () => {
  console.log('startTime', startTime)
  const currentTime = Date.now();
  console.log('currentTime', currentTime)
  const secondsDiff = Math.floor((currentTime - startTime) / 1000);
  console.log('secondsDiff', secondsDiff)
  document.body.innerText = secondsDiff;
  localStorage.setItem('myCat', secondsDiff);
 };
 intervalId = setInterval(writeTime, 1000);
 writeTime();
}



function resetTimelapsFunction() {
  localStorage.removeItem("myCat");
  localStorage.removeItem("startTime");
  clearInterval(intervalId)
}

You can give this a try.

var myInterval = null;

function startTimelapsFunction() {
  if (myInterval == null) {
    if (!localStorage.getItem('startTime')) {
      localStorage.setItem('startTime', Date.now());
    }

    const startTime = parseInt(localStorage.getItem('startTime'), 10);

    const writeTime = () => {
      console.log('startTime', startTime)
      const currentTime = Date.now();
      console.log('currentTime', currentTime)
      const secondsDiff = Math.floor((currentTime - startTime) / 1000);
      console.log('secondsDiff', secondsDiff)
      document.body.innerText = secondsDiff;
      localStorage.setItem('myCat', secondsDiff);
    };

    myInterval = setInterval(writeTime, 1000);
    writeTime();
  }
}

function stopTimelapsFunction() {
  if (myInterval != null) {
    clearInterval(myInterval);
    myInterval = null;
  }
}

function resetTimelapsFunction() {
  localStorage.removeItem("myCat");
  localStorage.removeItem("startTime");
  stopTimelapsFunction();
}

Store the intervalId returned by setInterval and run clearInterval(intervalId) where intervalId is the stored value (always an integer number for the timer you set)

let intervalId = null; // This creates a variable to identify which interval you are referring to

function startTimelapsFunction() {
    if (!localStorage.getItem('startTime')) {
      localStorage.setItem('startTime', Date.now());
    }
    
    
    const startTime = parseInt(localStorage.getItem('startTime'), 10);
    
    const writeTime = () => {
      console.log('startTime', startTime)
      const currentTime = Date.now();
      console.log('currentTime', currentTime)
      const secondsDiff = Math.floor((currentTime - startTime) / 1000);
      console.log('secondsDiff', secondsDiff)
      document.body.innerText = secondsDiff;
      localStorage.setItem('myCat', secondsDiff);
    };
    intervalId = setInterval(writeTime, 1000); // Here you assign the ID to the previously created variable
    writeTime();
    }
    


function resetTimelapsFunction() {
  localStorage.removeItem("myCat");
  localStorage.removeItem("startTime");
  clearInterval(intervalId) // Here you tell Javascript to clear that interval timer with the specific ID you provide it. This allows Javascript service workers to identify which specific interval you would like to clear if you create several.

}

This is from the Javascript docs:

The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().

Hope this helps! When coding you fluctuate between states of feeling like a God or a Dog, hopefully you're feeling like a God again ;)

This a problem with Life Cycle... follow this simple exemple to resolve your issue:

import React, { useEffect, useRef } from 'react';

function MyComponent() {

  const timestampRef = useRef(null); // verify if component exist
  const intervalRef = useRef(null); // save setInterval to when non exist component clear interval
  const startTime = useRef(() => {
    const { startTime = Date.now() } = localStorage; // if not exist value return Date.now()
      return startTime;
  });

  useEffect(() => {
    intervalRef.current = setInterval(() => { // save setInterval in intervalRef
      if (timestampRef.current) { // has component?
        const currentTime = Date.now(); 
        const secondsDiff = Math.floor((currentTime - startTime) / 1000);
        timestampRef.current.innerText = secondsDiff; // apply changes

        localStorage.setItem('startTime', parseInt(secondsDiff, 10)); // update localStorage
      }
      else {
        clearInterval(intervalRef.current); // no existe component, then, clearInterval
      };
    }, 1000);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [timestampRef]);

  return <div ref={timestampRef}>{startTime}</div>
};

export default MyComponent;

I hope this helpful!

Related