Amit Shah
Amit Shah

Reputation: 8179

Javascript setTimeout fires as many times in as page loaded by ajax

I am executing setTimeout function in a page which loads via ajax call. but if i click the link to load the page again, i afraid the last setTimeout call still continues and the number of intervals of the calls set by setTimeout executes multiple times.

tried this is the remote page:

var RefreshInterval = null;
clearTimeout(RefreshInterval);

function someFunction()
{
....
    setNextRefresh();

}

function setNextRefresh() {
    console.log(wifiRadarRefreshInterval);
    RefreshInterval = null;
    clearTimeout(RefreshInterval);
    RefreshInterval = setTimeout('someFunction();', 20*1000);
}

Upvotes: 2

Views: 335

Answers (3)

Rajshekar Reddy
Rajshekar Reddy

Reputation: 18987

Do not use this

var RefreshInterval = null;
clearTimeout(RefreshInterval);

You are actually assigning a null and then trying to clear it. Which will not work, The timeout must be cleared by using the clearTimeout and by passing the variable which was assigned to the setTimeout. Here you will end up passing a null so the timer is never cleared.

Here is a small sample which will demonstrate a fix to your problem JS Fiddle

So insted of setting the variable to null and then trying to clear it, Just check if the variable is not defined and if it is defined clear it, else move on. Use the code below, Also you must remove the top two lines as mentioned

   function setNextRefresh() {

     console.log(wifiRadarRefreshInterval);

     if (typeof RefreshInterval !== 'undefined') {
       clearTimeout(RefreshInterval);
     }

     RefreshInterval = setTimeout('someFunction();', 20*1000);
   }

Click on the button say like 4 times, The output should be printed only once. That is if the ajax call is made 4 times the set time out must execute only once. Check below snippet for demo

 var clickCount= 0; // just to maintain the ajax calls count

function NewPageSimilator(clicksTillNow) { // this acts as a new page. Let load this entire thing on ajaX call

  if (typeof RefreshInterval !== 'undefined') {
    clearTimeout(RefreshInterval);
  }

  function setNextRefresh() {
    window.RefreshInterval = setTimeout(printTime, 3000); //20*1000
  }

  function printTime() {// dumy function to print time  
    document.getElementById("output").innerHTML += "I was created at click number " + clicksTillNow + '<br/>';
  }
  setNextRefresh();
}

document.getElementById("ajaxCall").addEventListener("click", function() { // this will act as a ajax call by loading the scripts again
  clickCount++;
  NewPageSimilator(clickCount);
});

document.getElementById("clear").addEventListener("click", function() { //reset demo
  clickCount = 0;
  document.getElementById("output").innerHTML = "";
});
<p id="output">

</p>
<button id="ajaxCall">
  AJAX CALL
</button>
<button id="clear">
Clear
</button>

Upvotes: 0

Amit Shah
Amit Shah

Reputation: 8179

if i don't want to declare it in parent page, here is the solution i found:

//Clear previously loaded calls if exists
try{    clearTimeout(wifiRadarRefreshInterval); }catch(e){}
var wifiRadarRefreshInterval = null;

function somefunction(){
    ....
    setNextRefresh();
}

function setNextRefresh() {

    try{

        clearTimeout(wifiRadarRefreshInterval);
        wifiRadarRefreshInterval = null;
        wifiRadarRefreshInterval = setTimeout('somefunction();', 20*1000);
    }
    catch(e){
        console.log(e.message + e.stack);
    }   
}

Upvotes: 0

jcubic
jcubic

Reputation: 66490

declare var RefreshInterval = null; outside of page loaded by ajax and use this code on the page:

clearTimeout(RefreshInterval);

function someFunction()
{
....
    setNextRefresh();

}

function setNextRefresh() {
    console.log(wifiRadarRefreshInterval);
    clearTimeout(RefreshInterval);
    RefreshInterval = setTimeout('someFunction();', 20*1000);
}

Upvotes: 1

Related Questions