javaScript是單執行緒的語言:
眾所周知,javaScript是一門單執行緒語言;何為單執行緒?我的理解是:同一時間只能做同一件事;單執行緒在程式執行時,所走的程式路徑按照連續順序排下來,前面的必須處理好,後面的才會執行。
白話解釋:
假如去某銀行辦理業務,某銀行的單次業務接待總量為100個客戶,但此時在該銀行等待辦理業務的人數為150人,所以有50人是需要等待的,等待時間是未知;銀行採取叫號方式進行排隊辦理業務,前100個人是可以完成業務辦理的,此時這100個人形成了一個排隊的佇列,在計算機中我們稱之為執行緒;只有執行緒佇列中完成了任務或者空閒,剩下的50人才能繼續辦理業務;
javaScript為什麼會是單執行緒的語言?
在《javaScript高階程式設計》一書中有一個很好的解釋:如果JS是多執行緒語言,那麼假如當多個執行緒同時操作同一個DOM的時候,瀏覽器該如何渲染?瀏覽器該聽哪個執行緒的指令?渲染結果是否會超出預期?基於這個特性,JS必須只能是單執行緒語言;
程式與執行緒的區別:
程式:是cpu資源分配的最小單位;(能擁有獨立資源和獨立執行的最小單位)
執行緒:是cpu資源排程的最小單位;(執行緒是建立在程式基礎上一次程式最小的執行單位,一個程式中可以有多個執行緒)
resolve、.then、.catch等方法
才是非同步任務)、process.nextTick
解析圖文:
同步和非同步任務分別進入不同的執行"場所",同步的進入主執行緒,非同步的進入Event Table(任務佇列)並註冊函式。
當指定的事情完成時,Event Table(任務佇列)會將這個函式移入Event Queue(事件佇列)。
主執行緒內的任務執行完畢為空,會去Event Queue(事件佇列)讀取對應的函式,進入主執行緒執行。
上述過程會不斷重複迴圈,也就是常說的Event Loop(事件迴圈)。
舉個例子:
console.log('script start');
setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
輸出結果應為:
script start
script end
promise1
promise2
setTimeout
執行過程解析:
首先迴圈瀏覽器會執行第一步的同步任務,當執行到setTimeout的時候發現是非同步的巨集任務然後放入到任務佇列中,接著往下執行Promise.then,發現Promise.then也是非同步任務且是微任務,繼續放入到佇列中接著往下走執行"sciprt end " ;執行完"script end "之後發現主程式的同步任務都執行完了,然後開始執行非同步任務,非同步任務任務又分為巨集任務和微任務,我們前面說過微任務會優先於巨集任務執行;所以我們繼續執行" promise1 ",然後往下走發現還有個.then的微任務沒有執行,接著往下執行" promise2 ",至此所有的微任務執行完畢我們再去執行巨集任務" setTimeout ",所以最終的執行結果應該為:script start > script end > promise1 > promise2 > setTimeout
什麼?學會了?上面demo太簡單?那我們再看一下複雜一丟丟的例子來檢驗一下我們的學習成果
console.log('1'); setTimeout(() => { console.log('2') }, 1000); new Promise((resolve, reject) => { setTimeout(() => { console.log('3'); }, 0); console.log('4'); resolve(); console.log('5'); }).then(() => { console.log('6'); }); console.log('7');
這個例子是在上面例子的基礎上加以改造進行了巢狀