首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在循环中使用Coffeescript中的setTimout

如何在循环中使用Coffeescript中的setTimout
EN

Stack Overflow用户
提问于 2011-11-30 06:42:33
回答 2查看 4.2K关注 0票数 8
代码语言:javascript
运行
复制
window.onload = ->

  boxOrig1 = 10
  boxOrig2 = 30
  canvasW = 400
  canvasH = 300

  ctx = $("#canvas")[0].getContext('2d');

  draw = (origin,dimension) ->    
    ctx.clearRect(0, 0, canvasW, canvasH)
    ctx.fillStyle = 'rgb(200,0,0)'  
    ctx.fillRect(origin + boxOrig1, boxOrig1, dimension, dimension)  
    ctx.fillStyle = 'rgba(0, 0, 200, 0.5)'  
    ctx.fillRect(origin + boxOrig2, boxOrig2, dimension, dimension)

  for m in [10..100] by 10
    t = setTimeout (-> draw(m, 150)), 1000 
    t.clearTimeout
#     draw(m,150)
#     alert m

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

我可以看到,当我用警报中断循环时,机制工作得很好(就像在最后两个注释行中一样),但是我没有使用setTimeout函数获得预期的行为。设计只是在超时后出现在最右边的位置,跳过了中间的增量步骤。

我从其他例子中尝试了许多不同的方法来做这件事,但它只是融化了我的大脑。有什么建议吗?

EN

Stack Overflow用户

回答已采纳

发布于 2011-11-30 08:00:55

Geoff概述了一种方法(使用setInterval并从回调中清除它),因此我将概述另一种方法:从回调中使用setTimeout。就像这样

代码语言:javascript
运行
复制
m = 10
do drawCallback = ->
  draw m, 150
  m += 10
  setTimeout drawCallback, 1000 unless m > 100

请注意,这两种方法之间有一个细微的时序差异,您应该知道:setInterval func, 1000将每1000ms运行一次函数;链式setTimeout将在每次函数调用之间设置1000ms的延迟。因此,如果draw花了100ms,那么链接的setTimeout将等同于setInterval func, 1100。这可能无关紧要,但值得注意。

奖励方法:你不必放弃你的循环;你可以一次设置所有的超时:

代码语言:javascript
运行
复制
for m in [10..100] by 10
  do (m) ->
    setTimeout (-> draw(m, 150)), 100 * m

do (m)是必需的,这样传递给setTimeout的闭包才能看到m的每个值,而不仅仅是它在循环中的最终值。有关这方面的更多信息,请参阅我的文章A CoffeeScript Intervention

Finally:我知道这一切一开始看起来很混乱,但JS中的计时实际上非常简单,因为该语言是单线程的。这意味着您使用setTimeoutsetInterval或任何其他异步函数调度的事件在循环期间永远不会发生,即使循环是无限的。它们只有在所有代码执行完毕后才会发生。我将在my book on CoffeeScript中更详细地讨论这一点。

票数 11
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8318796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档