Hello,大家好,我是 Sunday。
【看代碼說結果】一直是前端面試中的常見問題。最近在陪幾個同學面試過程中,幾乎每個中、大廠的面試都會遇到一個或幾個這樣的問題。
雖然這樣的問題如此高頻,但是能夠回答好的同學卻寥寥無幾。
每次事后跟同學溝通,得到的結果都是:“實際開發中沒有這么寫的,NND 奇葩面試題!” 大家是不是也會有相同的感受呢?
是的!實際開發中我們肯定不會寫出面試題里的凌亂場景。但是,我們不要忘記,學習的目的是:為了拿到更高薪資的 offer!,所以對很多同學而言 面試 比 實際開發 更重要! 只有很好的解決了 面試 的問題,大家才可以拿到滿意的 offer。
所以,解決【看代碼說結果】的問題就變得至關重要了。那么咱們今天,就好好地來聊聊 JS 中的執行機制問題,幫大家徹底理解 JS 的執行邏輯!
JavaScript 是一種單線程語言。
雖然最新的 HTML5 中引入了 Web Worker,但 JavaScript 單線程的核心保持不變。
因此,JavaScript中所有的“多線程”都是用單線程模擬的,JavaScript中的所有多線程都是騙人的!
由于 JavaScript 是單線程的,它就像一家只有一個窗口的銀行,客戶需要一一排隊來處理交易。
同樣,JavaScript 任務也需要按順序執行,一個接一個。如果一項任務花費太長時間,則下一項任務必須等待。
那么問題就來了:如果我們想瀏覽新聞,但新聞中的高清圖片加載緩慢,我們的網頁是否要一直卡住,直到圖片完全顯示出來?
因此,JS將任務分為兩類:
當我們打開一個網站時,網頁的渲染過程由一堆同步任務組成,例如:骨架屏幕、頁面元素。
消耗大量資源且需要很長時間才能完成的任務(例如:加載圖像、音樂文件)則是異步的。
圖片
那么 JS 是如何知道主線程為空的呢?
在 JavaScript 引擎有一個監控進程,不斷檢查主線程執行棧是否為空。一旦為空,它就會去事件隊列檢查是否有任何函數正在等待調用。
如下面的代碼所示:
let data = [];$.ajax({ url:www.lgdsunday.club, data:data, success:() => { console.log('發送成功!'); }})console.log('代碼執行完成');
上面是一個簡單的ajax請求代碼:
通過上面的文字和代碼,大家應該對JavaScript中的執行順序有了初步的了解了吧。
那么接下來咱們來看一個 擾亂執行順序的 “元兇” setTimeout。
setTimeout 可以延遲執行代碼,比如:
setTimeout(() => { task();},3000)console.log('一個普通的打印');
根據我們之前的結論,setTimeout是異步的。所以,同步任務console.log應該先執行。因此,我們的結論是:
// 一個普通的打印// task()
但是,這里我們要注意 3000 毫秒并不是 task 的執行時間,而是 task 進入任務隊列(主線程)的時間
那么同樣的道理,在面試中常見的 setTimeout(fn, 0) 的延遲 0 毫秒 是什么意思呢?
setTimeout(fn ,0)是指定當堆棧中的所有同步任務完成且堆棧變空時,應在主線程上最早可用的空閑時間執行某個任務,而不需要等待任何額外的秒數。
所以,setTimeout(fn, 0) 并不會立刻執行。
宏任務與微任務的概念在這種題目中也是必須要掌握的。
事件循環中事件的順序決定了JavaScript代碼的執行順序。
我們通過一段代碼來看下這個問題:
setTimeout(function() { console.log('setTimeout');})new Promise(function(resolve) { console.log('promise');}).then(function() { console.log('then');})console.log('console');
本文鏈接:http://www.tebozhan.com/showinfo-26-89413-0.html這一次,徹底解決面試中看代碼說結果的問題!
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com