延迟脚本不工作
我在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
并且在打印完所有这些消息之后,图形(矩形)将绘制在画布上。 有没有办法做到这一点,而不使用setTimeout
或setInterval
?
问题 - 为什么fillRect
不能使用我的sleep
函数? 有没有一种方法来延迟JavaScript中的一些代码,而不使用setTimeout
和setInterval
?
您必须将您的sleep()函数实现为异步(即setTimeout()或setInterval())。您做到这一点的方式是阻止浏览器的所有操作,例如渲染和绘画;只有在将控件返回给浏览器后才绘制矩形。
那么为什么'alert'正在工作? – ShuklaSannidhya 2013-03-06 07:41:02
因为alert()也以阻塞的方式工作 - 它会立即中断您的js线程。 – 2013-03-06 07:46:21
“有没有得到这个无需使用setTimeout
或setInterval
做了呢?”没有,真的没有。您需要将每个步骤之间分隔为异步,并且定时器是异步的。
的问题是,只要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);
}
为什么不能使用canvas方法工作,当它使用'alert'正常工作? – ShuklaSannidhya 2013-03-06 07:42:52
@SandyLee对话如同alert一样,工作实际上取决于浏览器的开发者 - 他们并没有真正的标准化。但是,通常你看到的是他们工作,因为他们得到自己的线程,并暂停UI线程,直到他们被解雇。另一方面,'
有什么特别的原因你不能或不想使用这些?定时器通常是延迟代码执行的首选方式,因为它们允许其他代码/事件在此期间继续运行。 – 2013-03-06 07:06:25
@JonathanLonowski我正在避免这些,因为需要执行一些操作。把它们放在一个回调中,然后在满足某个条件后使用'clearTimeout'变得非常混乱。 – ShuklaSannidhya 2013-03-06 07:28:04