Js語言的執行環境是「單線程」。所謂"單線程",就是指一次只能完成一件任務。若是有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。
這種模式的好處是實現起來比較簡單,執行環境相對單純;壞處是隻要有一個任務耗時很長,後面的任務都必須排隊等着,會拖延整個程序的執行。常見的瀏覽器無響應(假死),每每就是由於某一段Javascript代碼長時間運行(好比死循環),致使整個頁面卡在這個地方,其餘任務沒法執行。
Java是多線程編程語言,本人並無接觸過多線程的編程語言,在此就略過。javascript
爲了同步模式下的阻塞問題,Js語言將任務的執行模式分紅兩種:同步和異步。
同步模式,即上面所說的模式,任務按排列順序執行;異步模式,其實就是延遲處理。在和HTML交互的過程當中,會須要一些IO操做(典型的就是Ajax請求,腳本文件加載),若是這些操做是同步的,就會阻塞其它操做,用戶的體驗就是頁面失去了響應。異步是經過異步函數實現的,如setTimeout()。html
下面看一個例子。java
var start = new Date(); setTimeout(function() { var current = new Date(); var dvalue = current - start; alert(dvalue + 'ms'); },500); while(new Date() - start < 1000) { }
我在google瀏覽器裏,運行的結果是1002ms,由於setTimeout和setInterval的計時精度問題,不一樣的瀏覽器裏獲得的數值可能稍微有出入。可是這個數值確定大於1000ms。
在這個例子裏,js按順序往下執行時,遇到setTimeout()函數,setTimeout()函數直接返回,裏面的回調函數被放入到事件隊列裏。js接着往下執行while循環。當時間差>=1000時,跳出循環,執行完畢。此時js纔會去處理隊列裏的事件。若是有適合「觸發」(就像1000ms以前設定好的延遲500ms的延時事件)的事件,則調用該事件的處理函數。事件處理器返回後,咱們又回到隊列處。
在這裏,咱們要詳細介紹下Javascript事件驅動機制。事件驅動通常經過事件循環(event loop)和事件隊列(event queue)來實現的。假定瀏覽器中有一個專門用於事件調度的實例(該實例能夠是一個線程,咱們能夠稱之爲事件分發線程event dispatch thread),該實例的工做就是一個不結束的循環,事件分發線程從事件隊列中取出事件,調度事件的排隊順序,並不執行代碼,注意回調函數是在Javascript的主線程中執行的,而非事件分發線程中,以保證事件處理不會發生阻塞。
在這裏要注意「觸發」和「執行」的區別。觸發只是插入隊列,執行纔是真正的執行代碼。這裏的分發線程和主線程應該就是對應觸發和執行這兩個概念。
經過事件驅動機制,咱們能夠想象Javascript的編程模型就是響應一系列的事件,執行對應的回調函數。不少UI框架都採用這樣的模型(例如Java Swing)。
暫時記錄到這裏,後續補充。
【
參考連接:
http://web.jobbole.com/82291/
http://www.ruanyifeng.com/blo...
】web