須要理解同步與異步咱們必須從單線程提及
複製代碼
js 自己是單線程的,單線程指的是同一時間段只能作同一件事情,也就是說兩段 js 代碼不能同時運行。網絡
js 是單線程的緣由是爲了不 dom 渲染時被污染dom
單線程會致使阻塞的問題,好比咱們一般把 script 標籤放在 body 標籤以後,這也是爲了解決單線程阻塞帶來的頁面短期空白的問題。異步
單線程就意味着,全部任務須要排隊,前一個任務結束,纔會執行後一個任務。若是前一個任務耗時很長,後一個任務就不得不一直等着。因而就有一個概念,任務隊列。若是排隊是由於計算量大,CPU忙不過來,倒也算了,可是不少時候CPU是閒着的,由於IO設備(輸入輸出設備)很慢(好比Ajax操做從網絡讀取數據),不得不等着結果出來,再往下執行。JavaScript語言的設計者意識到,這時主線程徹底能夠無論IO設備,掛起處於等待中的任務,先運行排在後面的任務。等到IO設備返回告終果,再回過頭,把掛起的任務繼續執行下去。因而,全部任務能夠分紅兩種,一種是同步任務(synchronous),另外一種是異步任務(asynchronous)。async
同步指的是代碼從上往下執行,只有上一個任務執行完以後纔會執行下一個任務,在主線程中運行,而且造成一個執行棧。
同步代碼:
```
console.log(1)
console.log(2)
console.log(3)
上面的代碼會依次輸出 1 2 3
```
複製代碼
異步指的是代碼不進入主線程的,而是進入一個任務隊列,只有在主線程中的代碼執行完以後纔會執行。
異步所在的問題,會致使回調地獄的出現,不利於代碼的封裝,可讀性差。
異步代碼:
```
console.log(1)
setTimeout(function() {
console.log(2)
}, 0)
console.log(3)
上面的代碼會輸出 1 3 2
獲得這樣的結果是由於 setTimeout 函數是異步的因此會將回調函數放入異步隊列中,等待主線程中的任務執行完以後,在執行回調函數即便延遲時間爲0。
```
複製代碼
異步的實現原理主要是經過事件輪詢也就是Event Loop來實現的具體步驟以下:
1. 同步代碼在主線程中從上往下開始執行,造成一個執行棧
2. 異步代碼發在異步隊列中
3. 當主線程中的代碼執行完以後,經過輪詢的方式來執行任務隊列中的代碼
4. 主線程不斷重複上第三個步驟
複製代碼