2011-08-03 98 views
14

我有一段代碼,需要執行一段時間後才能執行,例如5000 ms.Currently我正在使用setTimeout,但它是異步的,我希望執行等待它的返回。我曾嘗試使用以下嘗試:代碼執行中的同步延遲

function pauseComp(ms) 
{ 
    var curr = new Date().getTime(); 
    ms += curr; 
    while (curr < ms) { 
     curr = new Date().getTime(); 
    } 
} 

但我不想耽誤正在起草使用raphaeljs一些對象的代碼和顯示一點也不順利。我正在嘗試使用doTimeout插件。由於要延遲的延遲和代碼都處於循環狀態,因此我只需要延遲一次。我沒有要求的ID,所以我沒有使用它。 例如:

for(i; i<5; i++){ $.doTimeout(5000,function(){ 
     alert('hi'); return false;}, true);} 

此等待5秒befor給第一Hi和然後連續循環迭代之後緊接在第一顯示警告。我想要它做的是等待5秒,再次發出警報等待,然後給予警報等。

任何提示/建議表示讚賞!

回答

2

JavaScript是一種單線程語言。您不能合併setTimeout和同步處理。會發生什麼事,定時器會失效,但是然後JS引擎會等待處理結果,直到當前腳本完成。

如果你想要同步方法,直接調用方法!

如果您想在setTimeout之後處理某些內容,請將其包含或從超時函數中調用它。

3

非超時循環(檢查時間或計數到1000000或其他)只會鎖定瀏覽器。 setTimeout(或$.doTimeout插件)是最好的方法。

在循環中創建超時將不起作用,因爲在繼續之前,循環不會等待先前的超時發生,正如您發現的那樣。嘗試更多的東西是這樣的:

// Generic function to execute a callback a given number 
// of times with a given delay between each execution 
function timeoutLoop(fn, reps, delay) { 
    if (reps > 0) 
    setTimeout(function() { 
       fn(); 
       timeoutLoop(fn, reps-1, delay); 
       }, delay); 
} 

// pass your function as callback 
timeoutLoop(function() { alert("Hi"); }, 
      5, 
      5000); 

(我只是拼湊這個快起來,使其作品,雖然我相信它可以在幾個方面,如待提高,「循環」中它可以通過一個指數值放到回調函數中,這樣你自己的代碼就可以知道它要做什麼迭代了,但希望它能幫助你開始。)

+0

旁邊的setTimeout是一個更好的選擇,在OP請求syncronous方法@ThinkBonobo回答正確 – robsonrosa

+1

@robsonrosa - 的OP也說:」我不想耽誤代碼是畫些使用raphaeljs和顯示的對象並不是一帆風順的「,你不能使用同步代碼*和*繪製東西,因爲在同步代碼完成之前,屏幕不會被重新繪製,因爲OP要求的東西不會讓它成爲可能 – nnnnnn

20

對接受的答案的變化與此一樣好。

而且,我同意寧願setTimeout和異步函數調用,但有時如構造測試時,你只需要一個同步等待命令的注意事項...

function wait(ms) { 
    var start = Date.now(), 
     now = start; 
    while (now - start < ms) { 
     now = Date.now(); 
    } 
} 

如果你想讓它在幾秒鐘內,在開始毫秒的同時檢查...

+2

它應該是被接受的答案 – robsonrosa

0

我做了一個簡單的同步超時功能。它有兩種不同的方式,回調和非回調。

功能:

function wait(ms, cb) { 
    var waitDateOne = new Date(); 
    while ((new Date()) - waitDateOne <= ms) { 
    //Nothing 
    } 
    if (cb) { 
    eval(cb); 
    } 
} 

回調例如:

wait(5000,"doSomething();"); 

非回調例如:

console.log("Instant!"); 
wait(5000); 
console.log("5 second delay"); 
+1

使用'cb()'而不是'eval(db)'。腳本中的字符串不是一個好習慣。用法:'wait(5000,function(){console.log(「test!」)})'。順便說一句,如果你需要回調,最好使用setTimeout – Soaku

0

這裏是你如何使用JQuery的doTimeout插件

jQuery('selector').doTimeout([ id, ] delay, callback [, arg ... ]); 

docs:「如果回調返回true,則doTimeout循環將再次執行,延遲後,創建一個輪詢循環,直到回調返回一個非真正的價值。

var start = Date.now(); 
 
console.log("start: ", Date.now() - start); 
 
var i = 0; 
 
$.doTimeout('myLoop', 5000, function() { 
 
    console.log(i+1, Date.now() - start); 
 
    ++i; 
 
    return i == 5 ? false : true; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-dotimeout/1.0/jquery.ba-dotimeout.min.js"></script>