在Javascript

时间:2016-04-09 12:14:45

标签: javascript loops for-loop settimeout cleartimeout

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

如果某个条件为真,我在foor循环中设置Timeout函数。由于我不想在循环中声明Timeout,我编写了一个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函数内部更改它?

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

<强>问题:

  

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

     

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

     

是对var的引用   timeout_id没有给出并从setTimer函数内部改变它?

<强>答案:

发生了什么的原因是您传递的是primitive数字类型变量。

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

所以在这一行...

setTimer(timeout_id, 900);

...每次都传递undefined的值(不是对timeout_id的引用)

并且在这一行......

timer_id = setTimeout(function() {

... timer_id没有像你期望的那样持有对timeout_id的引用。

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

第一个console.log输出{{​​1}},因为这是作为参数传递的内容。

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

undefined返回递增的唯一整数id的原因是您可以将该ID粘贴到变量中,因此您可以在将来使用它来清除setTimeOut()

的超时

Here is a nice explanation of 'Passing by Value or by Reference'

答案 1 :(得分:1)

将setTimer函数更改为:

[[]]

答案 2 :(得分:0)

我很快就找到了解决方案。 通过返回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
你知道吗900毫秒后只有一个计时器正在完成。