2017-06-02 71 views
1

我是編程和編碼新手,我需要一個小項目的幫助。我需要在函數激活之前設置一個小的時間延遲。我正在使用HTML5畫布並嘗試重新創建pong。無論如何,想要在調用ballReset()函數之前放一小段時間延遲。另外,這不是整個腳本,它只是ballReset()函數被調用的部分。如何在JavaScript中爲函數添加時間延遲?

function moveEverything() { 
    computerMovement(); 

    ballX = ballX + ballSpeedX; 
    ballY = ballY + ballSpeedY; 

    if(ballX < 0) { 
     if(ballY > paddle1Y && 
      ballY < paddle1Y+PADDLE_HEIGHT) { 
      ballSpeedX = -ballSpeedX; 
     } else { 
      ballReset(); 
      player2Score++; 
     } 
    } 

    if(ballX > canvas.width) { 
     if(ballY > paddle2Y && 
      ballY < paddle2Y+PADDLE_HEIGHT) { 
      ballSpeedX = -ballSpeedX; 
     } else { 
      ballReset();  
      player1Score++; 
     } 
    } 
    if(ballY < 0) { 
     ballSpeedY = -ballSpeedY; 
    } 
    if(ballY > canvas.height) { 
     ballSpeedY = -ballSpeedY; 
    } 
} 
+2

你在尋找'setTimeout'嗎?你可以像這樣使用它:'setTimeout(function(){alert(「It was been 500 ms」)},500);' – Downgoat

+0

https://www.w3schools.com/js/js_timing.asp –

+0

下面的答案錯過解釋說,雖然'ballReset'調用將會延遲'setTimeout','moveEverything'中的其餘代碼將繼續執行,而不會等待'ballReset'被調用。你需要解釋爲什麼你想要這個延遲,以及它如何落入你的代碼邏輯的其餘部分。 – Igor

回答

0

你要找的是setTimeout FN,並通過FN ballReset()作爲回調!

例如,3000ms延遲,

setTimeout(function() { 
    ballReset() 
}.bind(this), 3000) 

你可以找到更多關於setTimeout在下面的文檔頁面https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

+0

正如OP所說,他們是編碼的新手,我認爲值得一提的是'setTimeout'是異步的並且不會執行 –

+3

匿名函數被綁定到'this'而不是在內部使用它的作用是什麼? – Igor

+0

如果你沒有任何參數ballReset,你可以做setTimeout(ballReset,3000); –

1

有兩個(大多采用)類型的定時器功能在JavaScript setTimeoutsetIntervalother

這兩種方法都有相同的簽名。他們以回呼功能和延遲時間爲參數。

setTimeout只在延遲後執行一次,而setInterval在每延遲秒後繼續調用回調函數。

這兩個方法都會返回一個整數標識符,在定時器到期之前可以使用它來清除它們。

clearTimeoutclearInterval這兩種方法採取從上述功能setTimeoutsetInterval

返回一個整數標識符示例:

setTimeout

alert("before setTimeout"); 

setTimeout(function(){ 
     alert("I am setTimeout"); 
    },1000); //delay is in milliseconds 

    alert("after setTimeout"); 

如果運行上面的代碼你會看到它提示before setTimeout然後after setTimeout最後它會提醒I am setTimeout後1秒(1000毫秒)

什麼,你可以從示例注意的是,該setTimeout(...)是異步的,這意味着它不會等待計時器之前得到經過去下一個陳述我。Ëalert("after setTimeout");

例子:

setInterval

alert("before setInterval"); //called first 

var tid = setInterval(function(){ 
     //called 5 times each time after one second 
     //before getting cleared by below timeout. 
     alert("I am setInterval"); 
    },1000); //delay is in milliseconds 

    alert("after setInterval"); //called second 

setTimeout(function(){ 
    clearInterval(tid); //clear above interval after 5 seconds 
},5000); 

如果你運行上面的代碼,你會看到,它提醒before setInterval然後after setInterval最後它提醒I am setInterval 5秒後1秒(1000毫秒),因爲setTimeout 5秒鐘後清除計時器,否則每1秒鐘您將獲得警報I am setInterval無限。

瀏覽器在內部如何做到這一點?

我會簡單介紹一下。

要了解您必須瞭解JavaScript中的事件隊列。瀏覽器中實現了一個事件隊列。每當一個事件在js中被觸發,所有這些事件(比如點擊等等)都被添加到這個隊列中。當您的瀏覽器無法執行時,它會從隊列中取出一個事件並逐個執行它們。

現在,當您撥打setTimeoutsetInterval時,您的回調將被註冊到瀏覽器中的一個計時器,並在給定時間過期後被添加到事件隊列中,並最終javascript從隊列中取出事件並執行它。

發生這種情況是因爲JavaScript引擎是單線程的,它們一次只能執行一件事。所以,他們不能執行其他的JavaScript並跟蹤你的計時器。這就是爲什麼這些定時器在瀏覽器中註冊(瀏覽器不是單線程),它可以跟蹤定時器並在定時器到期後在隊列中添加一個事件。

只有在這種情況下,該事件纔會在指定的時間間隔內一次又一次地添加到隊列中,直到它被清除或刷新瀏覽器頁面爲止,纔會發生setInterval

注意

傳遞給這些函數的延遲參數是最小延遲時間 執行回調。這是因爲在定時器到期之後,瀏覽器將該事件添加到隊列中以由 javascript引擎執行,但執行回調取決於隊列中的事件位置,並且由於引擎是單線程的,因此 將執行隊列中的所有事件一個接一個。

因此,當您的其他代碼阻塞線程並且沒有時間處理隊列中的內容時,您的回調可能需要超過指定的延遲時間。

正如我所說的JavaScript是單線程。所以,如果你長時間阻塞線程。

這樣的代碼

while(true) { //infinite loop 
} 

您的用戶可以得到一個消息,說頁面不響應

+0

如果您添加了代碼示例,我將滿足您的答案。我知道語法,但是我們的OP是編碼的新手,所以他們可能不會。 –