javascript – 如何在循环中的Coffeescript中使用setTimout

前端之家收集整理的这篇文章主要介绍了javascript – 如何在循环中的Coffeescript中使用setTimout前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_301_2@window.onload = -> @R_301_460@Orig1 = 10 @R_301_460@Orig2 = 30 canvasW = 400 canvasH = 300 ctx = $("#canvas")[0].getContext('2d'); draw = (origin,dimension) -> ctx.clearRect(0,canvasW,canvasH) ctx.fillStyle = 'rgb(200,0)' ctx.fillRect(origin + @R_301_460@Orig1,@R_301_460@Orig1,dimension,dimension) ctx.fillStyle = 'rgba(0,200,0.5)' ctx.fillRect(origin + @R_301_460@Orig2,@R_301_460@Orig2,dimension) for m in [10..100] by 10 t = setTimeout (-> draw(m,150)),1000 t.clearTimeout # draw(m,150) # alert m

作为练习,上面的代码是在画布上绘制一个小设计,暂停一秒,然后再向右重绘10个像素.

我可以看到,当我用警报中断循环时,机制工作正常(如最后两条注释行),但我没有得到setTimeout函数的预期行为.设计只是在超时后出现在最右边的位置,跳过两者之间的增量步骤.

我从其他例子中尝试了许多不同的方法,但它只是在融化我的大脑.有什么建议?

解决方法

Geoff概述了一种方法(使用setInterval并从回调中清除它),因此我将概述另一种方法:使用回调中的setTimeout.就像是 @H_301_2@m = 10 do drawCallback = -> draw m,150 m += 10 setTimeout drawCallback,1000 unless m > 100

请注意,您应该注意的两种方法之间存在细微的时序差异:setInterval func,1000将每1000ms运行一次该函数;链接的setTimeout将在每个函数调用之间放置1000ms的延迟.因此,如果绘制花费100毫秒,比如说,链接的setTimeout将等于setInterval func,1100.它可能无关紧要,但值得注意.

奖金方法:你不必放弃你的循环;您可以立即设置所有超时:

@H_301_2@for m in [10..100] by 10 do (m) -> setTimeout (-> draw(m,100 * m

do(m)是必要的,以便传递给setTimeout的闭包看到m的每个值,而不仅仅是它在循环中的最终值.有关详细信息,请参阅我的文章A CoffeeScript Intervention.

最后:我知道这一切看起来都很混乱,但JS中的时间实际上非常简单,因为语言是单线程的.这意味着在循环期间,使用setTimeout或setInterval或任何其他异步函数调度的事件将永远不会发生,即使循环是无限的.它们仅在所有代码完成执行后发生.我在my book on CoffeeScript更详细地讨论了这个问题.

猜你在找的JavaScript相关文章