重置Javascript中for循环中同一个定时器的超时时间

我想这可能是重复的,因为这个问题很简单,但我找不到任何答案。

如果某个条件为真,我将在一个foor循环中设置超时函数。 由于我不想在循环中声明超时,所以我写了一个setTimeout函数来设置它。 我只想使用一个定时器,如果它已经在运行,它将被重置,否则应该在第一次设置定时器。 我的问题是,该函数设置了多个定时器,尽管我使用了clearTimeout()。

我的代码:

    var timeout_id;
    var things = [true, true, false, true, true];

    var setTimer = function(timer_id, duration) {
        console.log("timer_id: ", timer_id);
        // clear timeout of the given Id
        clearTimeout(timer_id);
        timer_id = setTimeout(function() {
            // reset flag
            console.log("Timer timed out");
        }, duration);
        console.log("timer_id: ", timer_id);
    };

    for (var i = things.length - 1; i >= 0; i--) {
        if (things[i]) {
            setTimer(timeout_id, 900);
            console.log("Timer set because value of : " + i + " = ", things[i]);
        }
    }

我在控制台中得到的是:

timer_id:  undefined
timer_id:  1
Timer set because value of : 4 =  true
timer_id:  undefined
timer_id:  2
Timer set because value of : 3 =  true
timer_id:  undefined
timer_id:  3
Timer set because value of : 1 =  true
timer_id:  undefined
timer_id:  4
Timer set because value of : 0 =  true
timer timed out
timer timed out
timer timed out
timer timed out

我不明白为什么我的timer_id每次都增加。

我传递了id并重置了它的计时器。 之后,我在同一个ID上设置一个计时器,是不是? 是否给出了var timeout_id的引用,并从setTimer函数内部进行了更改?

谢谢您的帮助。


将您的setTimer函数更改为:

var timer_ids = {};

var setTimer = function(timer_id, duration) {
    console.log("timer_id: ", timer_id);
    // clear timeout of the given Id
    clearTimeout(timer_ids[timer_id]);
    timer_ids[timer_id]= setTimeout(function() {
        // reset flag
        console.log("Timer timed out");
    }, duration);
    console.log("timer_id: ", timer_id);
};

题:

我不明白为什么我的timer_id每次都增加。

我传递了id并重置了它的计时器。 之后,我在同一个ID上设置一个计时器,是不是?

是否给出了var timeout_id的引用,并从setTimer函数内部进行了更改?

回答:

发生什么的原因是您正在传递一个primitive数字类型变量。

原始类型变量作为值传递,而不是作为参考。

所以在这一行...

setTimer(timeout_id, 900);

...每次都传递未定义的值(而不是对timeout_id的引用)

并在这一行...

timer_id = setTimeout(function() {

... timer_id没有像您期待的那样持有对timeout_id的引用。

那么你的setTimer()函数发生了什么:

第一个console.log输出undefined因为这是作为参数传递的内容。

第二个console.log每次输出增加的id,因为这是setTimeout()函数在每次调用时返回的值。

setTimeOut()返回递增的唯一整数ID的原因是,您可以将该ID保存在一个变量中,因此您可以在将来使用它来使用clearTimeout( id )清除该超时值

以下是“按价值或参考值传递”的一个很好的解释


那么我很快就找到了解决方案。 通过返回timeout_id并在timeout_id变量上运行该函数,我只能得到一个运行的计时器:

    var timeout_id;
    var things = [true, true, false, true, true];

    var setTimer = function(timer_id, duration) {
        console.log("timer_id: ", timer_id);
        // clear timeout of the given Id
        clearTimeout(timer_id);
        timer_id = setTimeout(function() {
            // reset flag
            console.log("Timer timed out");
        }, duration);
        console.log("timer_id: ", timer_id);
        return timer_id;
    };

    for (var i = things.length - 1; i >= 0; i--) {
        if (things[i]) {
            timeout_id = setTimer(timeout_id, 900);
            console.log("Timer set because value of : " + i + " = ", things[i]);
        }
    }

哪些注销:

timer_id:  undefined
timer_id:  1
Timer set because value of : 4 =  true
timer_id:  1
timer_id:  2
Timer set because value of : 3 =  true
timer_id:  2
timer_id:  3
Timer set because value of : 1 =  true
timer_id:  3
timer_id:  4
Timer set because value of : 0 =  true
Timer timed out

你看。 900ms后只有一个定时器正在完成。

链接地址: http://www.djcxy.com/p/74993.html

上一篇: Reset Timeout of the same timer in a for loop in Javascript

下一篇: JavaScript function and UI updates