0

I need to write a setInterval function in javascript. Thi is the code:

var myTimer=setInterval(function(){ 
        var time=0;

        $.ajax({
            url:'...'
            type: "POST",
            dataType:"",
            success: function (response) {

                if(response=="true" || time>=10000){

                    clearInterval(myTimer);
                }
                time=time+1000;


            },
            error: function () {
                alert("FAIL");
            }
        });


        },1000);

I don't know why It doesn't stop in clearInterval. Anyone can help me?

Poppy
  • 3
  • 2
  • 1
    Have you [tried debugging it](http://stackoverflow.com/questions/988363/how-can-i-debug-my-javascript-code)? It's likely that response never equals `"true"` – Liam May 22 '15 at 09:52
  • yes it come in the "if" – Poppy May 22 '15 at 09:54
  • "true" try true without the quotations, that checks for the string "true" not an actual Boolean true – Lukas May 22 '15 at 09:56
  • 1
    Because your ajax request takes longer than 1000 ms, so the interval elapses many times before you clear it – Ahmad Ibrahim May 22 '15 at 09:58
  • 1
    probably same problem http://stackoverflow.com/questions/30368368/setinterval-loop-still-running-after-clearinterval-is-called – Ahmad Ibrahim May 22 '15 at 09:59
  • That's a good point, what do your mean by *It doesn't stop in clearInterval*? – Liam May 22 '15 at 09:59
  • @AhmadIbrahim my variable time is like a counter and It identifies how many times the $ajax function must be call. Also if my fuction takes more than one second it doesn't matter!. Why the clearInterval function doesn't stop the setInterval()? – Poppy May 22 '15 at 13:05

2 Answers2

2

You've claimed that the code does "come in the 'if'", so I assume the clearInterval call is actually being made.

Given that, the most likely explanation is that the interval is being cleared (after all, select isn't broken), but before the first "true" response, you've already made more than one ajax call, and the other ones you're seeing are ones scheduled before the interval was cleared.

E.g., your code runs and:

  1. Fires off ajax call #1, which takes more than a second to complete
  2. Fires off ajax call #2
  3. Ajax call #1 completes but isn't "true"
  4. Fires off ajax call #3
  5. Ajax call #2 completes and is "true", clearing the interval
  6. Ajax call #3 completes

Mixing two separate asynchronous intervals (one via setInterval and one via ajax) is asking for trouble.

If the goal is to make the request once a second and stop when you get back "true", I would have the success handler schedule the next call, e.g.:

(function() {
    var time = 0;
    var started = 0;

    start();

    function start() {
        started = Date.now();
        $.ajax({
            url: '...'
            type: "POST",
            dataType: "",
            success: function(response) {
                if (response != "true") {
                    // Schedule the next call to occur one second after we
                    // started the previous call; or almost immediately if
                    // the call took more than a second to complete
                    setTimeout(start, Math.max(0, 1000 - (Date.now() - started)));
                }
                time = time + 1000;
            },
            error: function() {
                alert("FAIL");
            }
        });
    }

})();
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Let me illustrate the expected and the actual scenarios to make things clearer.

Scenario #1

The image below shows the case where all your ajax requests complete before one second. You will notice that ajax callback success (or error) functions will execute only before clearInterval (which is what you always expect).

enter image description here

Scenario #2

When some of your ajax requests take more than one second (which is probably what happens), then your ajax callbacks can fire before / after / before-and-after the clearInterval, which makes you feel that your setInterval doesn't stop.

enter image description here

Note that your time variable is useless because it's a function-scoped variable that you initialize to 0 every function call. And even if it's a global variable, it'll only clear the interval in the 11th success function callback, and nothing guarantees how long these 11 successful requests will take.

Solution

As T.J. Crowder suggested, it's better to schedule the next ajax call in the success callback of the previous one, which guarantees that your ajax requests fire sequentially (only one at a time).

Note: Because you edited your question after his answer, then you'll also need to edit the if condition like this:

success: function(response) {
    if (response != "true" && time < 10000) {
    setTimeout(start, Math.max(0, 1000 - (Date.now() - started)));
    }
}
Community
  • 1
  • 1
Ahmad Ibrahim
  • 1,915
  • 2
  • 15
  • 32