简体   繁体   中英

Why my setInterval function doesn't stop

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?

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.

Eg, 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, eg:

(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");
            }
        });
    }

})();

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).

在此处输入图片说明

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 .

在此处输入图片说明

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 TJ 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)));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM