成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這一次,徹底解決面試中【看代碼說結果】的問題!

開發 前端
由于 JavaScript 是單線程的,它就像一家只有一個窗口的銀行,客戶需要一一排隊來處理交易。同樣,JavaScript 任務也需要按順序執行,一個接一個。如果一項任務花費太長時間,則下一項任務必須等待。

Hello,大家好,我是 Sunday。

【看代碼說結果】一直是前端面試中的常見問題。最近在陪幾個同學面試過程中,幾乎每個中、大廠的面試都會遇到一個或幾個這樣的問題。

圖片圖片

陪同學面試中遇到的真題

雖然這樣的問題如此高頻,但是能夠回答好的同學卻寥寥無幾。

每次事后跟同學溝通,得到的結果都是:“實際開發中沒有這么寫的,NND 奇葩面試題!” 大家是不是也會有相同的感受呢?

是的!實際開發中我們肯定不會寫出面試題里的凌亂場景。但是,我們不要忘記,學習的目的是:為了拿到更高薪資的 offer!,所以對很多同學而言 面試 比 實際開發 更重要! 只有很好的解決了 面試 的問題,大家才可以拿到滿意的 offer。

所以,解決【看代碼說結果】的問題就變得至關重要了。那么咱們今天,就好好地來聊聊 JS 中的執行機制問題,幫大家徹底理解 JS 的執行邏輯!

關于 JavaScript 線程基礎邏輯

JavaScript 是一種單線程語言。

雖然最新的 HTML5 中引入了 Web Worker,但 JavaScript 單線程的核心保持不變。

因此,JavaScript中所有的“多線程”都是用單線程模擬的,JavaScript中的所有多線程都是騙人的!

JavaScript 事件循環

由于 JavaScript 是單線程的,它就像一家只有一個窗口的銀行,客戶需要一一排隊來處理交易。

同樣,JavaScript 任務也需要按順序執行,一個接一個。如果一項任務花費太長時間,則下一項任務必須等待。

那么問題就來了:如果我們想瀏覽新聞,但新聞中的高清圖片加載緩慢,我們的網頁是否要一直卡住,直到圖片完全顯示出來?

因此,JS將任務分為兩類:

  • 同步任務
  • 異步任務

當我們打開一個網站時,網頁的渲染過程由一堆同步任務組成,例如:骨架屏幕、頁面元素

消耗大量資源且需要很長時間才能完成的任務(例如:加載圖像、音樂文件)則是異步的

圖片圖片

  • 同步和異步任務進入不同的執行“地方”,同步任務進入主線程,異步任務進入事件表并注冊函數。
  • 當指定的任務完成時,事件表會將這個函數移動到事件隊列中。
  • 主線程內的任務完成后,會從Event Queue中讀取相應的函數并在主線程中執行。
  • 上述過程會不斷重復,通常稱為事件循環。

那么 JS 是如何知道主線程為空的呢?

在 JavaScript 引擎有一個監控進程,不斷檢查主線程執行棧是否為空。一旦為空,它就會去事件隊列檢查是否有任何函數正在等待調用。

如下面的代碼所示:

let data = [];
$.ajax({
    url:www.lgdsunday.club,
    data:data,
    success:() => {
        console.log('發送成功!');
    }
})
console.log('代碼執行完成');

上面是一個簡單的ajax請求代碼:

  • ajax進入事件表并注冊回調函數success。
  • 執行console. log(‘發送成功!’)。
  • ajax事件完成,回調函數成功進入事件隊列。
  • 主線程success從事件隊列中讀取并執行回調函數。

通過上面的文字和代碼,大家應該對JavaScript中的執行順序有了初步的了解了吧。

那么接下來咱們來看一個 擾亂執行順序的 “元兇” setTimeout

萬惡的 setTimeout

setTimeout 可以延遲執行代碼,比如:

setTimeout(() => {
    task();
},3000)
console.log('一個普通的打印');

根據我們之前的結論,setTimeout是異步的。所以,同步任務console.log應該先執行。因此,我們的結論是:

// 一個普通的打印
// task()

但是,這里我們要注意 3000 毫秒并不是 task 的執行時間,而是 task 進入任務隊列(主線程)的時間

  • 3秒后,計時事件timeout完成。
  • task()進入任務隊列(主線程)

即面試中常提到的 setTimeout 定時并不準確的問題 字節面試:如何實現準時的setTimeout 可以看下之前的這篇文章

那么同樣的道理,在面試中常見的 setTimeout(fn, 0) 的延遲 0 毫秒 是什么意思呢?

setTimeout(fn ,0)是指定當堆棧中的所有同步任務完成且堆棧變空時,應在主線程上最早可用的空閑時間執行某個任務,而不需要等待任何額外的秒數。

所以,setTimeout(fn, 0) 并不會立刻執行

宏任務與微任務

宏任務與微任務的概念在這種題目中也是必須要掌握的。

  • 宏任務:包括整體腳本代碼、setTimeout、setInterval
  • 微任務:Promise、process.nextTick

事件循環中事件的順序決定了JavaScript代碼的執行順序。

  • 輸入整個腳本(宏任務)后,它開始第一個循環
  • 然后它執行所有微任務。接下來,又從宏任務開始,直到一個任務隊列完成后,才再次執行所有的微任務

我們通過一段代碼來看下這個問題:

setTimeout(function() {
    console.log('setTimeout');
})

new Promise(function(resolve) {
    console.log('promise');
}).then(function() {
    console.log('then');
})

console.log('console');
  • 這段代碼作為宏任務,進入主線程。
  • 當遇到 setTimeout 時,其回調函數被注冊并調度到宏任務事件隊列中。(注冊流程同上,下文不再贅述)
  • 接下來,當遇到 Promise 時,new Promise立即執行,并將該then函數分派到微任務事件隊列中。
  • 當遇到 console.log() 時,立即執行。
  • 在將整個腳本作為第一個宏任務執行之后。我們發現它 then 位于微任務事件隊列中并被執行。
  • 第一輪事件循環結束
  • 第二輪循環開始;當然是從宏任務Event Queue開始。隊列中對應setTimeout的回調函數立即被執行
  • 結尾
責任編輯:武曉燕 來源: 程序員Sunday
相關推薦

2025-04-09 10:36:32

2024-05-20 00:00:00

代碼主線程

2024-05-15 10:14:00

CRDT數據類型協同編輯

2019-11-08 16:05:54

Promise前端鏈式調用

2024-03-11 08:47:30

CRDT數據類型協同編輯

2019-09-12 09:40:34

秒殺系統高并發

2018-08-07 14:45:52

編程語言JavaScripthtml

2021-07-03 08:59:49

動態代理JDK

2020-09-28 14:41:24

Event Loop

2021-08-29 08:14:30

GPU CSS gpu

2019-06-05 13:00:00

2019-04-12 11:25:24

華為

2020-08-13 07:04:45

跨域CORS瀏覽器

2016-03-31 17:01:26

桂林甲天下

2018-07-23 16:13:27

Google歐盟Android

2021-03-11 12:15:37

Kubernetes云原生容器

2014-07-18 17:14:16

小米蘋果雷軍

2016-01-06 11:15:03

VR

2016-11-08 07:58:02

樂視難關科技新聞早報

2021-04-28 09:55:52

JavaLock接口并發編程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产目拍亚洲精品99久久精品 | 亚洲一区二区视频 | 欧美精品一二区 | 亚洲电影一区二区三区 | 欧美激情在线精品一区二区三区 | 国产视频精品区 | 夜夜爽99久久国产综合精品女不卡 | 可以免费观看的av片 | 欧美日韩在线一区 | 国产精成人 | 涩涩视频网站在线观看 | 亚洲精品一 | 999久久久久久久 | 看羞羞视频免费 | 青青久久 | 成人欧美一区二区 | 欧美黄在线观看 | 欧美精品片 | 国产激情91久久精品导航 | 亚洲一二三区免费 | 欧美一区二区三区视频 | 欧美激情区 | 久久精品男人的天堂 | 精品国产91乱码一区二区三区 | 欧美日一区 | 国产无套一区二区三区久久 | 一区二区三区免费 | 精品一二三区 | 99久久久无码国产精品 | 在线观看免费黄色片 | 天堂色网 | 国产亚洲精品久久久优势 | 国产高清免费在线 | 99精品99| 午夜一区二区三区在线观看 | 亚洲v日韩v综合v精品v | 久久久久欧美 | 日韩一区二区三区在线播放 | 国产日韩欧美一区 | 欧美 日韩 国产 成人 在线 91 | 国产小视频在线 |