3

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

如果某个条件为真,我将在 foror 循环中设置超时函数。因为我不想在循环中声明超时,所以我编写了一个 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 函数内部对其进行更改?

谢谢您的帮助。

4

3 回答 3

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 输出undefined,因为这是作为参数传递的。

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

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

这是对“按值传递或按引用传递”的一个很好的解释

于 2016-04-09T12:22:56.383 回答
1

将您的 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);
};
于 2016-04-09T12:21:46.777 回答
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 毫秒后完成。

于 2016-04-09T12:19:28.720 回答