如何将变量添加到setTimeout名称?

时间:2014-02-10 23:43:44

标签: javascript settimeout

我想以不同的方式命名许多setTimeout,以便我可以单独清除每个。我尝试了以下方法:

for(i=0; i<5; i++){

    var wordTimeout = i + "_T_i_m_e_o_u_t";     
    clearTimeout( wordTimeout ); 

    var wordTimeout = setTimeout( function() { console.log( i + ' timeout called' );}, 2000); 
    console.log(i);
}

http://jsfiddle.net/NU4E8/2/

但看起来我重命名了wordTimeout,然后变量无所谓。理想情况下,在此示例中,所有setTimeout在被调用后都会被单独清除。因此,日志中不会显示任何超时。谢谢。

3 个答案:

答案 0 :(得分:4)

您无法命名自己的超时时间。 setTimeoutsetInterval会返回一个数字ID,这是必须传递到clearTimetout的内容。但是,您可以使用数组或对象来存储超时:

var timeoutIds = [];
for(var i=0; i<5; i++){
    timeoutIds.push(setTimeout(function(){ /* ... */ }));
}

或者,如果您需要为它们命名,您可以这样做:

var timeoutIds = {};
for(var i=0; i<5; i++){
    timeoutIds['timeout_' + i] = setTimeout(function(){ /* ... */ });
}

你还应该知道,在你的循环中,正如你所写的那样,所有的超时都会打印'4超时调用';这是因为函数在包含i的闭包中声明,并且当它们执行时,循环将完成,并且具有最终值4(除非它被其他代码重用)同样的范围,当然)。您可能想要做的是:

var timeoutIds = [];
for(var i=0; i<5; i++){
    timeoutIds.push(
        (function(i){
            // i now captured as a function-scope variable
            return setTimeout(function(){ console.log(i + ' timeout called'); });
        })(i)
    );
}

这会创建一个immediately-invoked function expression (IIFE),它将i的值“捕获”为函数范围变量。

答案 1 :(得分:3)

您可以创建一个数组并使用索引作为键来存储计时器引用,如

var timers = [];
for (i = 0; i < 5; i++) {
    timers.push(setTimeout(function () {
        console.log(i + ' timeout called');
    }, 2000));
    console.log(i);
}

然后使用定时器[0]

访问i=0的定时器参考

您还有另一个常见问题,即在循环中使用闭包变量

答案 2 :(得分:0)

创建一个数组,您可以在其中存储每个setTimeout调用返回的数字。

var timeouts=[];
for(i=0; i<5; i++){    
    clearTimeout(timeouts[i]);
    timeouts[i]=setTimeout((function(){
        console.log(this.i+' timeout called');
    }).bind({i:i}),2000); 
    console.log(i);
}

然后,当您需要进行清算时,您将i存储超时号码。

.bind技巧是因为i的范围。