JQuery日記6.5 Javascript異步模型(一)

在瞭解JQuery的異步隊列實現之前,有必要去了解javascript的異步模型.
Javascript的異步其實並不算嚴格意義上的異步,js的異步是指讓某段代碼片段在將來再執行,而不是讓執行流不必等待繼續向下進行.
在多線程的語言中最容易想到的異步方式就是在當前線程中,新創建一個線程讓某段代碼片段運行在新創建的線程中,從而使當前線程繼續向下進行.
而任何一本書關於js的書都會告訴我們js是運行在單線程裏的,這個線程稱爲UI線程,從名字就知道這個線程不光用於運行js代碼,還負責事件的處理和UI的繪製.
在遊覽器內部維護着一個事件隊列,觸發的事件會一個個的放進這個隊列中,UI線程在空閒時會去查看這個隊列,如果隊列不爲空,就取第一個事件並執行其監聽函數.
for (var i = 0; i < 3; ++i) {
    setTimeout( function(){
         console.info( 'setTimeout: ' + i);
    }, 0);
    console.info( 'for循環: ' + i)
}
上面這段代碼在UI線程的執行示意圖圖如下

首先將此段js代碼放進UI線程中執行,當代碼執行到setTimeout(fn, mills)時,遊覽器會在事件隊列中放入此定時事件1,前面說過只有當UI線程空閒時纔會去執行定時事件,但此時js代碼還在執行,所以繼續for循環,i繼續自增,並且繼續放入定時事件2,3,當js代碼片段執行完畢後,才繼續依次執行定時事件1、2、3,此時i的值已經是3了.所以在控制檯中我們看到的打印結果依次是:setTimeout:1,setTimeout:2,setTimeout:3,for循環:3,for循環:3,for循環:3.
其實這樣看起來非常類似與傳統多線程的異步編程,代碼執行流並不會等setTimeout的函數執行完畢,再繼續向下執行.但我們要了解的是,其實它們仍然是串行執行的,只不過是把setTimeout中設置的函數放到隊列中延後執行,從而使js代碼依然先執行,執行完畢後再依次執行事件隊列中的函數.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章