2011-09-14 62 views
19

我正在使用setInterval()函數每20秒調用一次函數。不過,我注意到的一件事是,它實際上第一次調用該函數的時間是20秒(而不是當調用setInterval()時)。這是我目前的解決方法:JavaScript:如何讓setInterval()立即開始?

dothis(); 
var i = setInterval(dothis, 20000); 

有什麼辦法來實現這一目標,而不必此重複的代碼?

回答

29

你的方法是這樣做的正常方式。

如果這個遍地出現,你可以做,將首先執行的處理程序,然後設置間隔實用功能:

function setIntervalAndExecute(fn, t) { 
    fn(); 
    return(setInterval(fn, t)); 
} 

然後,在你的代碼,你可能只是這樣做:

var i = setIntervalAndExecute(dothis, 20000); 
+0

有用的信息。謝謝! – Andrew

2

如果你的dothis函數沒有其他需要的返回值,你可以讓它自己返回。

這將允許您調用並同時傳遞它。如果返回值被忽略,它將是無害的。

function dothis() { 
    // your code 
    return dothis; 
} 

var i = setInterval(dothis(), 20000); 

否則,你可以擴展Function.prototype給予的調用和返回功能,所有功能:

DEMO:http://jsfiddle.net/ZXeUz/

Function.prototype.invoke_assign = function() { 
    var func = this, 
     args = arguments; 
    func.call.apply(func, arguments); 
    return function() { func.call.apply(func, args); }; 
}; 

setInterval(dothis.invoke_assign('thisArg', 1, 2, 3), 20000); 

// thisArg 1 2 3 
// thisArg 1 2 3 
// thisArg 1 2 3 
// ... 

這實際上提高了事情有點。它可以讓你傳遞一組參數。第一個參數將設置您調用的函數的this值,其餘參數將作爲常規參數傳遞。

因爲返回的函數被封裝在另一個函數中,所以在初始調用和間隔調用之間會有相同的行爲。

10

您可以創建一個匿名函數並立即調用它,除非您使用setTimeout函數而不是setInterval。

(function doStuff() { 
    //Do Stuff Here 
    setTimeout(doStuff,20000); 
})(); 

這將執行該函數,然後在20秒內再次調用它。

請注意,根據您希望的行爲或某些情況下的性能,最好使用setTimeout over setInterval。主要區別在於,只要超時結束,setInterval就會調用該函數,如果最後一次調用已完成或發生錯誤,則返回無效。使用setTimeout可以確保函數在定時器重置之前完成其執行。許多權衡是非常明顯的,但在設計應用程序時記住它是一件好事。

編輯迴應帕特里克dw的關注需要取消超時。最好的解決辦法是不使用匿名函數,並調用它的聲明後

var timeout; 
function doStuff() { 
    //doStuff 
    timeout = setTimeout(doStuff,20000); 
} 
doStuff() 

是的,這是類似於在OP試圖避免的,但它確實消除了需要調用的函數,然後調用setInterval函數,所以你保存了一行代碼。您可以隨時通過以下方式停止並啓動該功能:

//Stop it 
clearTimeout(timeout); 

//Start it 
doStuff(); 
+0

加上:'setTimeout'比較好,因爲如果有錯誤,它不會繼續重複。 – Hemlock

+0

+1我認爲如果沒有其他需要從外部調用該函數,這是一個很好的解決方案。 – user113716

+0

...雖然你現在的答案正在失去一點功能。 OP將'setInterval'的返回結果賦值給一個變量,這可能意味着該區間應該在某個時刻被取消。爲了複製行爲,你需要通過'setTimeout'進行遞歸調用,這取決於可以設置爲停止調用的標誌的狀態。 – user113716