對aimingoo的JavaScript時鐘間隔的問題~一文的回複:
12月21日更新:aimingoo又寫了一個總結,從底層上解釋了16ms的原因。
時間間隔是約數,通常會認為在10ms-20ms之間,來源應該是win的時鐘限制。為什麼沒有人確切的說是16ms?因為這個16ms來源於不準確的new Date!
function test() {
var dates = [];
var d = new Date();
count = 0;
while (count < 10) {
var x = new Date();
var t = x.getTime() - d.getTime();
if (t > 0) {
dates.push(t);
d = x;
count++;
}
}
alert(dates);
}
上面這個test在xp下運行,也是列印出15,16...。也就是時鐘精度就只有這點。
但是放到vista上看就會發現不同了,會出現1,1,1,1...,說明vista上的時鐘精度提高了!但是setInterval的結果是形如16,3,18,16,13,18,13,17,21,9,8,22,1,6...這樣的。
所以,xp系統上的16ms間隔反映的是時鐘精度,而不是真實的interval間隔值,真實的間隔值可能是一個難以度量的隨機值。
在ff上出現0的情況,並不是因為java的問題(ff可以不啟用java的),而是因為ff允許0間隔(即與ie不一樣,如setInterval可以設0ms),比方說前一個任務做了太久後面一個會立即跟上,而ie和opera至少休息一個周期。
BTW,實際上setTimeout和setInterval的實現上當無差異,之所以不同是因為我們代碼書寫方式的不同,假如習慣於在幹活的代碼之前而不是之後寫下一個setTimeout,那可能就沒有差別了。反之,在幹活後setTimeout可以確保出讓足夠的cpu時間,而setInternal就可能始終霸佔著cpu。如果要做一個給其他人用的任務調度器,則就應該使用setTimeout。比如說做動畫效果的timeline,我傾向於使用單一的setTimeout來構建任務隊列,然後執行動畫運算時,根據目前時間來計算,而不是幀數,這樣在cpu不行的情況下,就類似於跳幀的效果。如果自己執行一些單純的小任務,能保證不會耗費過多cpu,用setInterval就很直接方便了。