先看一段代碼:javascript
運行這段腳本能夠看到:Time elapsed的值大概在1001ms左右,確定會超過1000ms。也就是說:setTimeout失效了,指定的函數並無在500ms後執行,而是延遲到1000ms後才執行。html
再看一段代碼:java
運行這段腳本能夠看到:先打印2後打印1,咱們在setTimeout裏面指定了0ms,但願能當即執行,可是實際上沒有效果。瀏覽器
想要理解上面的2段代碼,咱們得了解一下JavaScript中setTimeout的實現原理。首先牢記一點:JavaScript 是單線程執行的,也就是沒法同時執行多段代碼。下面這段解釋來自這篇博客:異步
JavaScript是單線程執行的,沒法同時執行多段代碼。當某一段代碼正在執行的時候,全部後續的任務都必須等待,造成一個隊列。一旦當前任務執行完畢,再從隊列中取出下一個任務,這也常被稱爲 「阻塞式執行」。因此一次鼠標點擊,或是計時器到達時間點,或是Ajax請求完成觸發了回調函數,這些事件處理程序或回調函數都不會當即運行,而是當即排隊,一旦線程有空閒就執行。假如當前 JavaScript線程正在執行一段很耗時的代碼,此時發生了一次鼠標點擊,那麼事件處理程序就被阻塞,用戶也沒法當即看到反饋,事件處理程序會被放入任務隊列,直到前面的代碼結束之後纔會開始執行。若是代碼中設定了一個 setTimeout,那麼瀏覽器便會在合適的時間,將代碼插入任務隊列,若是這個時間設爲 0,就表明當即插入隊列,但不是當即執行,仍然要等待前面代碼執行完畢。因此 setTimeout 並不能保證執行的時間,是否及時執行取決於 JavaScript 線程是擁擠仍是空閒。函數
也就是說setTimeout只能保證在指定的時間事後將任務(須要執行的函數)插入隊列等候,並不保證這個任務在何時執行。執行javascript的線程會在空閒的時候,自行從隊列中取出任務而後執行它。javascript經過這種隊列機制,給咱們製造一個異步執行的假象。this
如今咱們知道了setTimeout的原理了,如今看下setTimeout(0)的使用場景。下面這個例子來自這篇文章。spa
這段代碼使用了setTimeout(0)就能夠實現須要的效果了。這裏其實涉及2個任務,1個是將鍵盤輸入的字符回寫到輸入框中,一個是獲取文本框的值將其寫入div中。第一個是瀏覽器自身的默認行爲,一個是咱們本身編寫的代碼。很顯然,必需要先讓瀏覽器將字符回寫到文本框,而後咱們才能獲取其內容寫到div中,若是當即執行獲取文本框的值,其實輸入框尚未輸入的內容。改變順序,這這正是setTimeout(0)的做用。.net
原文連接:http://blog.csdn.net/aitangyong/article/details/46800615線程
儘管setTimeout的delay是0,也會做爲一次異步調用,而每次異步調用結束後都會render頁面