祝賀《JavaScript 秘密花園》中文翻譯被官方正式採納,大家以後可以隨時通過官方網站瀏覽:http://bonsaiden.github.com/JavaScript-Garden/zh/
由於這是一個不斷更新的文檔,如果有新的更新或者錯誤修正我會及時更新中文翻譯。
這篇文章的起因是有網友提的 Issue: https://github.com/BonsaiDen/JavaScript-Garden/issues/#issue/68
大致意思說是原文對 setInterval 的描述不大準確,而 Stackoverflow.com 上的描述才算正確。本著學習的態度,我又仔細看了兩個描述:
JavaScript 秘密花園:
當回呼函數的執行被阻塞時,setInterval
仍然會發布更多的毀掉指令。在很小的定時間隔情況下,這會導致回呼函數被堆積起來。
Stackoverflow.com:
intervals try to ‘catch up’ to get back on schedule. But, they don't queue one on top of each other: there can only ever be one execution pending per interval.
x represents an interval firing that couldn't execute or be made pending, so instead was discarded.
爭論的焦點是:如果回呼函數需要花很長的時間執行(比定時時間長的多),那些這些回呼函數會不會被堆積起來?
目前 《JavaScript 秘密花園》的意思是會堆積起來,而 Stackoverflow 的那篇文章的意思是一些來不及執行的回調會被丟棄,特別的那個圖形描述很生動:
. * • • x • • x
[------][------][------][------]
為了驗證誰對誰錯,我寫了一段 JavaScript 代碼: http://jsfiddle.net/sanshi/3XLHc/
var count = 0, start = new Date(), interval;function loop() { var i, time; if (count <= 5) { for (i = 0; i < 1000000000; i++) {} } time = new Date() - start; $('#result').append("<li>time:" + time + " - count:" + count + '</li>'); count++; if (count >= 15) { clearInterval(interval); }}interval = setInterval(loop, 1000);
執行結果:
- time:2840 - count:0
- time:4668 - count:1
- time:6489 - count:2
- time:8358 - count:3
- time:10180 - count:4
- time:12002 - count:5
- time:12004 - count:6
- time:13004 - count:7
- time:14001 - count:8
- time:15001 - count:9
- time:16002 - count:10
- time:17003 - count:11
- time:18017 - count:12
- time:19017 - count:13
- time:20018 - count:14
可見,count 等於 5 時,時間已經過去了12 秒鐘,如果按照 JavaScript 秘密花園 中的說法,此時累計的回呼函數已經有 12 - 5 = 7 個了,那麼在下面如果回呼函數執行時間很短的情況下會連續執行,但是實際情況並非如此,以後的回調都是 1 秒為間隔的。
也就是說一些 setInterval 的回調被丟棄了。所以 Stackoverflow 的那篇文章的描述是正確的。
我會隨後更新這個改動到中文翻譯中(可能要一周后,最近在老家沒網路了。。。)。