JavaScript 非同步操作原理

admin發表於2018-12-07

本文只簡述JavaScript非同步原理,並不會對細節做過多介紹。

一.非同步操作:

與非同步操作對應的是同步操作。

所謂同步操作,就是同一時刻只能做一件事情,如果要多件事情需要處理,需要排隊。

非同步操作是同一時刻能夠做多件事情,比如銀行開多個視窗同時辦理業務。

JavaScript中常見一個非同步操作是,當ajax非同步向伺服器請求資料的同時,可以繼續處理其他事務。

二.非同步操作原理:

JavaScript雖然是單執行緒的,好像不能實現非同步操作。

然而它的執行環境瀏覽器是多執行緒的,這是實現非同步的決定性因素。

瀏覽器可以包含如下主要執行緒:

(1).JavaScript引擎。

(2).介面渲染。

(3).瀏覽器事件

(4).http(s)請求

下面是一張網路上比較關於此方面比較著名的圖片:

aid[2664]

圖示說明:

(1).tn:表示不同的時刻。

(2).tn下方方塊:表示tn時刻正在執行或者將要執行的程式碼。

非同步原理解析:

(1).介面渲染:

大家知道JavaScript程式碼預設會阻塞程式碼的執行,自然包括介面的渲染。

因為JavaScript程式碼可以操作介面的內容,所以要等待程式碼執行完畢再去渲染。(2).定時器函式:

JavaScript中有兩個定時器函式,分別是setTimeout與setInterval。

這兩個函式都可以進行時間計數,但是需要注意的是,計數功能並不是由JavaScript引擎完成。

因為JavaScript是單執行緒的,如果有其他任務在執行,那就無法計數了,所以定時器也是非同步的。

(3).圖示分析:

t1時刻正在執行一個回撥函式,t2時刻通過點選觸發click事件,瀏覽器事件也是一個獨立的執行緒,所以同樣是非同步操作,將事件處理函式放入執行佇列。click事件處理函式不會立刻執行,而是要等待t1時刻的程式碼執行完畢。隨著時間的推移,定時器函式的回撥函式不斷放入佇列等待執行。也就是說,定時器與事件等操作都是非同步的,當時放入JavaScript引擎執行緒的程式碼還是要排隊執行的。舉個簡單的例子:

[JavaScript] 純文字檢視 複製程式碼
setTimeout(function(){
  console.log("螞蟻部落");
},1000)
while(true){
  //code
}

程式碼的初衷是1000毫秒後列印字串"螞蟻部落",所以會首先執行while語句。

在執行while語句的同時,計數器正常計數(因為它不屬於JavaScript引擎執行緒,不會被堵塞)。

到達1000毫秒後,定時器將會回撥函式放入JavaScript引擎執行緒佇列。

然而,while語句是一個死迴圈,所以回撥函式永遠得不到執行。

相關文章