2013-03-06 175 views
1

我在Javascript成为延迟脚本不工作

function sleep(ms) { 
     var d = new Date(); 
     var target=d.getTime()+ms; 
     var next = d; 
     console.log('Slept'); 
     while(next.getTime()<=target) { 
      next=new Date(); 
     } 
     console.log('Woke Up'); 
     return; 
    } 

睡眠功能对象(控制台)

Slept 

5秒

Woke Up 
后使用此 sleep(5000)打印出来

此代码也正常工作 - alert('foo'); sleep(5000); alert('bar'); 第一个foo和5秒钟后bar

但这个功能

//ctx is a 2d context of a canvas 
function go() { 
    ctx.fillRect(100,100,200,200); 
    sleep(1000); 
    ctx.fillRect(200,200,300,300); 
    sleep(1000); 
    ctx.fillRect(300,300,400,400); 
    sleep(1000); 
    ctx.fillRect(400,400,500,500); 
} 

go(); 

不工作。我的意思是它正在工作,但不是它应该的方式。首先控制台显示 -

Slept 
//1 second later 
Woke Up 
//1 second later 
Slept 
//1 second later 
Woke Up 
Slept 
//1 second later 
Woke Up 

并且在打印完所有这些消息之后,图形(矩形)将绘制在画布上。 有没有办法做到这一点,而不使用setTimeoutsetInterval

问题 - 为什么fillRect不能使用我的sleep函数? 有没有一种方法来延迟JavaScript中的一些代码,而不使用setTimeoutsetInterval

+1

有什么特别的原因你不能或不想使用这些?定时器通常是延迟代码执行的首选方式,因为它们允许其他代码/事件在此期间继续运行。 – 2013-03-06 07:06:25

+0

@JonathanLonowski我正在避免这些,因为需要执行一些操作。把它们放在一个回调中,然后在满足某个条件后使用'clearTimeout'变得非常混乱。 – ShuklaSannidhya 2013-03-06 07:28:04

回答

2

您必须将您的sleep()函数实现为异步(即setTimeout()或setInterval())。您做到这一点的方式是阻止浏览器的所有操作,例如渲染和绘画;只有在将控件返回给浏览器后才绘制矩形。

+0

那么为什么'alert'正在工作? – ShuklaSannidhya 2013-03-06 07:41:02

+1

因为alert()也以阻塞的方式工作 - 它会立即中断您的js线程。 – 2013-03-06 07:46:21

1

有没有得到这个无需使用setTimeoutsetInterval做了呢?”没有,真的没有。您需要将每个步骤之间分隔为异步,并且定时器是异步的。

的问题是,只要sleep(...)正在运行,这是阻挡 UI线程。再次,免费再次,浏览器无法使用您绘制的图形来更新显示。

给执行甚至1毫秒的突破给了它足够的时间步长之间更新:“*?有没有得到这个没有使用的setTimeout或setInterval的实现方式*”

function go() { 
    ctx.fillRect(100,100,200,200); 
    sleep(1000); 
    ctx.fillRect(200,200,300,300); 
    sleep(1000); 
    setTimeout(function() { 
     ctx.fillRect(300,300,400,400); 
     sleep(1000); 
     ctx.fillRect(400,400,500,500); 
    }, 1); 
} 
+0

为什么不能使用canvas方法工作,当它使用'alert'正常工作? – ShuklaSannidhya 2013-03-06 07:42:52

+1

@SandyLee对话如同alert一样,工作实际上取决于浏览器的开发者 - 他们并没有真正的标准化。但是,通常你看到的是他们工作,因为他们得到自己的线程,并暂停UI线程,直到他们被解雇。另一方面,''完全取决于执行JavaScript和管理UI的相同线程。 – 2013-03-06 07:50:07