如何使用setTimeout正确地让浏览器在循环中更新?

时间:2014-09-09 01:26:09

标签: javascript html5

我正在尝试使用javascript在html5画布上生成一系列图像。这是我已经拥有的一个小提琴:http://jsfiddle.net/ws5e3rw6/1/

function loopColors(){
  for (r=0; r<1; r++){
      for (g=0; g<1; g++){
          for (b=0; b<256; b+=50){
              setTimeout(drawImage,1000,r,g,b);
          }
      }
  }
}

我已经看到了很多关于这个主题的建议,这真的令人沮丧,因为它们似乎都不适合我。我试过一个匿名函数,比如:

function loopColors(){
  for (r=0; r<1; r++){
      for (g=0; g<1; g++){
          for (b=0; b<256; b+=50){
              setTimeout(function(){drawImage(r,g,b);},1000);
          }
      }
  }
}

但那也行不通。

此刻,点击按钮后,等待一秒钟,然后立即跳转到最后一个蓝色。我不明白为什么。

我对javascript很新,所以我可能会遗漏一些明显的东西。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

廉价的解决方案是每秒安排回调,而不是一秒钟安排回调。

请注意,为了使代码合理运行,您需要捕获循环变量的值,否则所有回调都将具有相同的值(如果您的代码实际上将值传递给drawImage函数)。

function createCallback(r,g,b)
{
   return function(){drawImage(r,g,b);}; 
}

function loopColors(){
  var timeout = 10;
  for (r=0; r<1; r++){
    for (g=0; g<1; g++){
      for (b=0; b<256; b+=50){
          setTimeout(createCallback(r,g,b), timeout);
          timeout += 1000;
      }
    }
  }
}

正确的解决方法是将循环内部转换为每次返回下一组值(1,1,1),(1,1,2),...并且每秒都有一个函数。