Js的同步異步以及回調函數

這裏是修真院前端小課堂,每篇分享文從javascript

【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】html

八個方面深度解析前端知識/技能,本篇分享的是:前端

【Js的同步異步以及回調函數】java

 
你們好,我是IT修真院深圳分院第06期學員,一枚正直善良的web程序員。
今天給你們分享一下,修真院官網JS任務中可能會使用到的知識點:
js同步異步以及回調函數
1.背景介紹
什麼是同步,什麼是異步?git

同步指的是一次只能完成一件任務。若是有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。
異步指的是每個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,因此程序的執行順序與任務的排列順序是不一致的、異步的。
2.知識剖析
javascript實現異步的原理程序員

首先js是單線程的語言,即同一時間只能作作一件事。那Js如何實現異步的,異步和單線程不是自相矛盾嗎?其實,單線程和異步確實不能同時成爲一個語言的特性。js選擇了成爲單線程的語言,因此它自己不多是異步的,但js的宿主環境(好比瀏覽器,Node)是多線程的,宿主環境經過某種方式(事件驅動,下文會講)使得js具有了異步的屬性github

瀏覽器的內核是多線程的,它們在內核制控下相互配合以保持同步,一個瀏覽器至少實現三個常駐線程:javascript引擎線程,UI渲染線程,瀏覽器事件觸發線程。web

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

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

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

clipboard.png

image

UI線程和JS線程互斥的實例

<input type="text" value="" name="input" onkeydown="console.log(this.value)">
<input type="text" value="" name="input" onkeydown="var me=this;setTimeout(function(){console.log(me.value)},0)">

分析:第一個在keydown的時候,彈出來的是input裏原來的value,而第2個在keydown的時候,卻能彈出更新後的value,就是由於setTimeout,雖然他的delay設置爲0,幾乎是即時觸發,但仍是被添加到了執行隊列後面,但就是這個過程,渲染已經完成了,當他回調函數執行時,輸出來的已是更新後的value了。

注意:js的工做機制是當線程空閒的狀況下才會執行異步代碼的回調函數

即當全部同步任務執行完畢後纔會執行異步任務的回調函數

總結:當Js執行到異步任務後,會將異步任務交給瀏覽器進行執行,當執行有結果時會把異步任務的回調函數插入待處理隊列的隊尾。

3.常見問題
ajax發送異步請求瀏覽器作了什麼
有哪些常見異步回調函數?
4.解決方案
ajax發送異步請求瀏覽器作了什麼?
Js建立了一個ajax請求
瀏覽器另外開啓一個ajax引擎線程,執行ajax請求
執行獲得響應後將回調函數放入任務隊列中。
Js執行任務隊列中的回調函數。
有哪些常見的異步回調函數?
點擊事件
Ajax請求
定時器
瀏覽器處理點擊事件的過程
瀏覽器開啓事件觸發線程,等待用戶動做,事件觸發線程解析爲響應事件,轉移到javascript引擎線程,排隊等候,等待javascript引擎的處理。
例:

<!doctype html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<div onclick="clickme()">click me</div>
<script type="text/javascript">
    function clickme() {
        console.log('點擊事件')
    }
    for (i=0;i<50000;i++){
        console.log(i)
    }
</script>
</body>
</html>

在線實例
這個點擊事件會等到for循環執行完畢後纔會執行,即咱們點擊模塊它直到for循環執行完畢纔會執行

5.編碼實戰
6.擴展思考
如何實現js的多線程操做?

Html5的web worker
7.更多討論
Q1:瀏覽器的UI線程和Js線程爲何是互斥的?

A1:而由於JS能夠操做DOM元素,進而會影響到GUI的渲染結果,所以JS引擎線程與GUI渲染線程是互斥的。
Q2:異步函數有哪些優勢和缺點

A2:
優勢:
a)對CPU的使用率高。
b)不用考慮線程間同步互斥問題。
缺點:
a)實現較複雜,要把全部會致使阻塞的操做轉化爲異步操做。
b)併發性很差,在有的事件須要長時間佔用CPU處理的狀況下,其餘事件會長時間等待得不處處理。
c)在多CPU時不如多線程高效。
Q3:異步函數跟promise之間有什麼關係?

A3:Promise它能夠用於異步的回調函數,它跟傳統的回調函數相比,promise的異步回調函數代碼書寫起來更優雅,更便於閱讀。
8.參考文獻
參考一:js的單線程和異步
參考二:深刻理解javascript異步編程障眼法&&h5 web worker實現多線程
參考三:談談JavaScript的異步實現- 小方- 博客園
PPT
視頻

相關文章
相關標籤/搜索