Why isn't clearInterval working in this code?

2019-07-16 18:14发布

问题:

There is a function which sets an interval using setInterval(), but even after calling clearInterval(), I can see in the console that the else condition is still running. How can I clear that interval properly?

function increase(old, step, neu) {
    var i = 0;
    var delay2;

    function countUp() {
        if (i < 5) {
            old += step;
            // console.log("increase")
            $("#total-price-value").text(old + " dollors");
            $("#total-price-value").digits();
            i++;
            delay2 = setInterval(countUp, 80);
        } else {
            clearInterval(delay2);
            console.log(delay2);
        }

    }
    countUp();

}​

回答1:

It looks like you're a little confused about the difference between timeouts and intervals. Timeouts fire only once; intervals fire many times. If you're using an interval, you probably only want to set it once (you're setting it every time). If you're using a timeout, you probably want to set it every time (like you're doing).

In order to fix the problem, you'll either want to switch to timeouts (probably the easiest; just a search/replace) or only set the interval once.

For example, here is how one might use setTimeout to count up to five:

var count = 0;
function timeoutFired() {
    count++;
    if(count < 5) {
        setTimeout(timeoutFired, 1000);
    }
}
setTimeout(timeoutFired, 1000);

Using timeouts, we don't need to clear to stop it from counting; simply not setting a timeout will prevent it from running again.

Here is how one might use setInterval:

var count = 0;
function intervalFired() {
    count++;
    if(count >= 5) {
        clearInterval(interval);
    }
}
var interval = setInterval(intervalFired, 1000);

If you want some code running periodically using intervals to stop, you must call clearInterval. Note that we only call setInterval once, versus setTimeout every time we didn't want it to continue.



回答2:

Apparently, you have mistaken setInterval for setTimeout. setInterval runs the enclosed function every n milliseconds while setTimeout executes only once after n milliseconds.

I suppose you wanted to "tick until 5" so here's a sample:

function increase(old, step, neu) {
    var i = 0;

    interval = setInterval(function() {
        if (i < 5) {

            //do something at this "tick"
            console.log(i);

            i++;
        } else {
            //else, stop
            clearInterval(interval);
        }
    },80);

}

increase();