无法在for循环中设置setTime

时间:2016-11-27 10:10:22

标签: javascript html css

我正在建造一个西蒙游戏。每轮比赛结束后,球员应该看到他必须在下一轮比赛中发挥的动作。所以我创建了一个函数showMoves,它闪烁了他必须播放的方块。问题是该功能没有显示任何内容。谁能告诉我我错过了什么?

// the effect
function flasher(index) {
     $(moves[index]).fadeIn(50).fadeOut(50).fadeIn(50).fadeOut(50).fadeIn(100);
}
var interval2;
// show the moves that supposed to be played
function showMoves() {
    for (var i = 0; i < moves; i++) {
        if (i === 0) {
            interval2 = setTimeout(flasher(i), 1000);
        } else {
            interval2 = setTimeout(flasher(i), (i+1) * 1000);
        }
     }
 }

3 个答案:

答案 0 :(得分:1)

setTimeout接受函数作为第一个参数。我假设通过致电flasher您试图避免this situation。在你的情况下,这应该这样做:

  function showMoves() {
    for (var i = 0; i < moves; i++) {
      if (i === 0) {
        interval2 = setTimeout(function(i) {return function() {flasher(i)}}(i), 1000);
      } else {
        interval2 = setTimeout(function(i) {return function() {flasher(i)}}(i), (i+1) * 1000);
      }
    }
  }

答案 1 :(得分:0)

setTimeout和setInterval与我们想到的有点不同。 它们会在特定时间保存一些事件,这些事件将在其时间内触发。因此,他们遇到了循环问题:

for(i=0;i<3;i++)
{
setTimeout(function(){alert(i)}, i*1000);
}

结束循环后,浏览器有3个工作要做:

alert(i) after 1 second
alert(i) after 2 seconds
alert(i) after 3 seconds

但是&#39; i&#39;的价值是什么?如果你在结束循环之后进行c#编程,那么我就会#c;编程。将被处理,我们没有。 但javascript没有处理&#39;我&#39;我们还有它。因此浏览器将i的当前值设置为3.因为当&#39; i&#39;达到3循环结束。为此您的浏览器执行此操作:

alert(3) after 1 second
 alert(3) after 2 seconds
 alert(3) after 3 seconds

这不是我们想要的。但是如果将上面的代码更改为:

for(i=0;i<3;i++){
      (function (index)
            {
                setTimeout(function () { alert(index); }, i * 1000);
            })(i);
}

我们将:

alert(0) after 1 second
alert(1) after 2 seconds
alert(2) after 3 seconds

因此,Maximus说你使用浏览器获取i当前循环的值。这样:

setTimeout(function(i) {return function() {flasher(i)}}(i), (i+1) * 1000);

我不会遗漏直到循环结束,并且必须立即获得价值。

答案 2 :(得分:0)

我可以从你的代码中得到的是moves是一个数组,但是你正在使用它,好像它是for循环中的一个整数。这就是为什么没有任何事情发生的原因。

替换:

for (var i = 0; i < moves; i++) {

使用:

for (var i = 0; i < moves.length; i++) {

你应该看到事情正在发生。

但是你会注意到flasher被立即调用,没有超时。这是因为flasher的结果设置为调用,而不是flasher本身 这里的其他答案建议使用包装函数,但这需要解决方法才能正确地将索引传递给setTimeout调用的函数。 因此,假设它不必在IE8及更低版本中运行,以下是最简洁的解决方案:

setTimeout(flasher.bind(null, i), (i+1) * 1000)

完整的工作示例:

var moves = [1, 2, 3, 4];

function flasher(index) {
    console.log('move', moves[index]); 
}
var interval2;
// show the moves that supposed to be played
function showMoves() {
    for (var i = 0; i < moves.length; i++) {
        interval2 = setTimeout(flasher.bind(null, i), (i+1) * 1000);
    }
 }
 
 showMoves()