同步與異步

同步方式: 代碼是順序執行的,而且發送請求的時候界面會阻塞。CPU按順序執行,前一個任務結束,再執行下一個任務.javascript

異步模式: 界面不會阻塞,主線程會當即返回,等到異步請求完成的時候再從線程池中取一個線程處理。CPU跳過等待時間長的任務,先處理後面的任務.java

[1] JavaScript運行瀏覽器

JavaScript引擎是單線程運行的,瀏覽器不管在何時都只且只有一個線程在運行JavaScript程序.瀏覽器的內核是多線程的,它們在內核制控下相互配合以保持同步,一個瀏覽器至少實現三個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。這些異步線程都會產生不一樣的異步的事件.數據結構

                                     

1. javascript引擎是基於事件驅動單線程執行的,JS引擎一直等待着任務隊列中任務的到來,而後加以處理,瀏覽器不管何時都只有一個JS線程在運行JS程序。多線程

2. GUI渲染線程負責渲染瀏覽器界面,當界面須要重繪(Repaint)或因爲某種操做引起迴流(reflow)時,該線程就會執行。但須要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JS引擎空閒時當即被執行。異步

3. 事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器內核的其餘線程如鼠標點擊、AJAX異步請求等,但因爲JS的單線程關係全部這些事件都得排隊等待JS引擎處理。(當線程中沒有執行任何同步代碼的前提下才會執行異步代碼)函數

[2] JavaScript運行機制oop

程序中跑兩個線程,一個負責程序自己的運行,做爲主線程; 另外一個負責主線程與其餘線程的的通訊,被稱爲「Event Loop 線程" 。每當遇到異步任務,交給 EventLoop 線程,而後本身日後運行,等到主線程運行完後,再去 EventLoop 線程拿結果。線程

1)全部任務都在主線程上執行,造成一個執行棧(execution context stack)。blog

2)主線程以外,還存在一個"任務隊列"(task queue)。系統把異步任務放到"任務隊列"之中,而後繼續執行後續的任務。

3)一旦"執行棧"中的全部任務執行完畢,系統就會讀取"任務隊列"。若是這個時候,異步任務已經結束了等待狀態,就會從"任務隊列"進入執行棧,恢復執行。

4)主線程不斷重複上面的第三步。

"回調函數"(callback),就是那些會被主線程掛起來的代碼。異步任務必須指定回調函數,當異步任務從"任務隊列"回到執行棧,回調函數就會執行。"任務隊列"是一個先進先出的數據結構,排在前面的事件,優先返回主線程。主線程的讀取過程基本上是自動的,只要執行棧一清空,"任務隊列"上第一位的事件就自動返回主線程。

Event Loop(事件循環): 主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,因此整個的這種運行機制又稱爲Event Loop。

Event Loop 是一個很重要的概念,指的是計算機系統的一種運行機制。

JavaScript語言就採用這種機制,來解決單線程運行帶來的一些問題。

                                        

[3] 異步setTimeout & setInterval

setTimeout:在指定的毫秒數後,將定時任務處理的函數添加到執行隊列的隊尾。

setInterval:按照指定的週期(以毫秒數計時),將定時任務處理函數添加到執行隊列的隊尾。

從主線程的角度看,一個異步過程包括下面兩個要素:

發起函數(或叫註冊函數)A

回調函數callbackFn

它們都是在主線程上調用的,其中註冊函數用來發起異步過程,回調函數用來處理結果。

setTimeout(fn, 1000);

其中的setTimeout就是異步過程的發起函數,fn是回調函數。

用一句話歸納:工做線程將消息放到消息隊列,主線程經過事件循環過程去取消息。

消息隊列:消息隊列是一個先進先出的隊列,它裏面存放着各類消息。

事件循環:事件循環是指主線程重複從消息隊列中取消息、執行的過程。

                                  

相關文章
相關標籤/搜索