2011-08-22 102 views
3

我試圖做一個函數,以確切的時間間隔開始保持stanble更新率。問題在於它似乎在2個通道中執行。這是日誌:JavaScript setTimeout運行兩次

timeElapsed=141; lastDraw=1314040922291 
timeElapsed=860; lastDraw=1314040923151 
timeElapsed=141; lastDraw=1314040923292 
timeElapsed=860; lastDraw=1314040924152 
timeElapsed=141; lastDraw=1314040924293 
timeElapsed=860; lastDraw=1314040925153 
timeElapsed=141; lastDraw=1314040925294 
timeElapsed=860; lastDraw=1314040926154 
timeElapsed=141; lastDraw=1314040926295 
timeElapsed=859; lastDraw=1314040927154 
timeElapsed=143; lastDraw=1314040927297 
timeElapsed=858; lastDraw=1314040928155 
timeElapsed=143; lastDraw=1314040928298 
timeElapsed=858; lastDraw=1314040929156 
timeElapsed=142; lastDraw=1314040929298 

首先,我exectute使用

drawTimer = setTimeout(function(){ draw() }, 1); 

我的功能和作用如下:

var draw = function(){ 
    if(!running) 
     return; 

    var miliseconds = getCurrentMiliseconds(); 
    var timeElapsed = miliseconds - lastDraw; 
    lastDraw = miliseconds; 

    console.log("timeElapsed=" + timeElapsed + "; lastDraw=" + lastDraw); 
    onDrawListener(timeElapsed); 

    if(timeElapsed < timeLapse) 
     miliseconds = timeLapse - timeElapsed; 
    else 
     miliseconds = 1;   

    drawTimer = setTimeout(function(){ draw() }, miliseconds); 
} 

它發生在這兩個,Chrome和Firefox瀏覽器。你知道它是什麼造成的?而...如何解決它?

P.S.由於每個人似乎對運行變量的如此困惑,因此它是:它是一個私有父對象成員,用於指示機制是否仍在運行或已停止。它由其他函數設置,並在那裏確保此函數在stop()被調用後不會繼續工作。

- update - timeLapse設置爲1000(每秒1次)並且再也不會更改。

onDrawListener設置這個功能:

function(timeElapsed){ 
     canvas.clear(); 

     moveSnake(); 

     if(snake.body[0] == food){ 
      food = getRandomFreePosition(); 
      ++snake.body.lenght; 
     } 


     drawBackground(); 
     drawFood(); 
     drawSnake(); 

    } 

來解釋它:畫布是有點那個照顧回調,關鍵聽的,也有一些功能的引擎。除此之外,似乎有點自我解釋。除了一些int算法和在畫布中繪圖之外,他們什麼都不做。

- 想通了 - 我知道我應該計算花費在當前函數上的時間,而不是從最後一個函數開始後的時間。我的舊方法不是在2個頻道,而是在長 - 短 - 長 - 短 - 長... - 延遲

+0

你需要什麼drawTimer呢? – PeeHaa

+0

另外,爲什麼你在這種情況下不使用'setInterval'?除非你期望迭代的執行時間比間隔時間長,否則它可以爲你簡化一些事情。 – Tejs

+0

@Tejs他不能使用setInterval,因爲他希望每次更改時間間隔(每調用一次函數,他都會重新計算「milisecond」) – Paulpro

回答

2

首先,你不設置運行布爾,並且當你立即進入函數做一個clearTimeout在drawTimer上。

clearTimeout(drawTimer); 
+0

我設置了運行,但它是一種外部方式來阻止循環功能,因此它被設置在函數之外。但這不是原因。我不知道即使完成時也必須清除超時(稱爲函數)。那是我的問題。將盡快標記此答案。 – Pijusn

+0

事情發生了。首先,當我將代碼添加到我的代碼中,並且它作爲一種魅力工作時,但在寫入消息之後,我刷新了瀏覽器,並且雙重運行效果又回來了。 WTF? – Pijusn

+0

你可以顯示什麼是onDrawListener,什麼是timeLapse? – Baz1nga

0

在這樣一個循環,你應該考慮寫:

if(timeElapsed >= AMOUNT_OF_TIME) 
{ 
// run code 
}