2013-03-06 216 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