看一個簡單的例子:javascript
1 for(var i=0; i<4; i++){ 2 setTimeout(function(){console.log(i)}, 0); 3 }
請問下這段代碼會輸出什麼呢?java
若是你以爲輸出:多線程
1函數
2spa
3線程
那你就錯了,實際上它會輸出code
4blog
4隊列
4事件
爲何是這個結果呢?這裏給出的解釋是:Javascript事件處理器是在線程執行完以後才執行事件,繼續看下面的例子,你會更清楚:
var start = new Date(); setTimeout(function(){ var end = new Date(); console.log('多少秒以後才執行的setTimeout:', end - start, 'ms'); }, 500); while(new Date() - start < 1000){}
若是按照多線程的思惟定勢,咱們可能會以爲500毫秒以後函數就會執行,可是實際的結果可能會是:
多少秒以後才執行的setTimeout:1002 ms
若是要詳細解釋這個結果,咱們可能還要看一下javascript中關於隊列的解釋。
由於javascript是單線程運行語言,因此當出現上面的代碼運行的時候,javascript會先執行循環,把setTimeout事件放到事件隊列裏面,等待線程空閒,一旦線程空閒了,javascript會從事件隊列中的底部堆棧中取出以前註冊的事件執行,因此setTimeout會有很大的精度問題。