一道面試題window.setTimeout(() => { test1() }, 0); test2(); test1和2 誰先執行,考察js的異步機制和事件循環基礎

答案: test2()先執行,然後再執行test1()。

原因:JS是單線程的,(PS: 雖然html5中提出了新的web標準,允許javascript 腳本創建多個線程,但子線程完全受主線程控制,且不得進行Dom操作,因此也並沒有改變單線程的本質。)

setTimeout屬於異步操作,JS引擎會把setTimeout的操作加入到JS的任務隊列中去,test2()屬於主線程上的同步操作,優先執行,等主線程上的同步操作都執行完畢,主線程空閒,纔會去讀取任務隊列,再執行test1();

僅僅是知道答案是遠遠不夠的,這裏面用到的知識,也需要整理一下,越學越發現自己懂得越少。

一:js的同步和異步?

js語言的執行環境是“單線程”。所謂"單線程",就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。

同步模式,即上面所說的模式,在主線程上排隊執行的任務,任務按排列順序執行,只有前一個任務執行完畢,才能執行後一個任務;

異步模式,其實就是延遲處理。不進入主線程、而進入"任務隊列"(task queue)的任務,只有等主線程任務執行完畢,"任務隊列"開始通知主線程,請求執行任務,該任務纔會進入主線程執行。在和HTML交互的過程中,會需要一些IO操作(典型的就是Ajax請求,腳本文件加載),如果這些操作是同步的,就會阻塞其它操作,用戶的體驗就是頁面失去了響應。異步是通過異步函數實現的,如setTimeout()。

二:什麼是事件循環?

主線程中的所有同步任務執行完畢,再讀取任務隊列中的異步任務,這個過程是循環不斷的。所以,整個的這種運行機制稱爲Event Loop(事件循環)。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章