日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

彻底搞懂JavaScript执行机制

發(fā)布時間:2025/4/5 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 彻底搞懂JavaScript执行机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

首先我們大家都了解的是,JavaScript 是一門單線程語言,所以我們就可以得出:

JavaScript 是按照語句順序執(zhí)行的

首先看:

let a = '1' console.log(a)

let b = '2' console.log(b) 這個顯然大家都知道結(jié)果,依次輸出1,2

然而換一種:

setTimeout(function() { console.log(1) })

new Promise(function(resolve) { console.log(2) for(var i = 0;i< 10;i++){ i === 10 && resolve() } }).then(function() { console.log(3) }) console.log(4) 這個時候再看代碼的順序執(zhí)行,輸出1,2, 3, 4。好了放到瀏覽器運行一下,什么?輸出居然是 2, 4, 3,1。說好的按順序執(zhí)行呢?下面就需要去了解一下 JavaScript 的執(zhí)行機(jī)制問題了。

單線程 首先JavaScript 是一門單線程的語言,在最新的HTML5 推出的 Web-worker,但是 JavaScript 是一個單線程的語言這一個核心還是沒有改變。所以,JavaScript 的多線程都是基于單線程模擬出來的。所以牢記 JavaScript 是單線程語言。

事件循環(huán) 任務(wù)分為兩類:

同步任務(wù) 異步任務(wù) 當(dāng)我們打開頁面時,頁面的渲染就是一大堆同步任務(wù),而像加載圖片和音頻資源耗時的任務(wù),就是異步任務(wù)。時間循環(huán)的主要內(nèi)容就是:

當(dāng)任務(wù)進(jìn)入執(zhí)行棧的時候,判斷是同步任務(wù)還是異步任務(wù),如果是同步任務(wù),進(jìn)入主線程進(jìn)行執(zhí)行,異步進(jìn)入 Event Table 進(jìn)行注冊函數(shù)。 當(dāng)指定的事件完成后,Event Table 將這個函數(shù)移入到事件隊列 主線程中的任務(wù)執(zhí)行完畢后,去任務(wù)隊列讀取對應(yīng)的函數(shù),進(jìn)入主線程執(zhí)行 上述的過程不斷重復(fù),也就構(gòu)成了事件循環(huán) 其中js引擎存在一個監(jiān)控進(jìn)程,不斷檢查主線程執(zhí)行棧是否為空,一旦為空,就會去時間隊列那檢查有沒有等待被調(diào)用的函數(shù)。

例如:

setTimeout( function() { console.log(1) }, 0) console.log(2) 首先 setTimeout進(jìn)入Event Table 執(zhí)行console.log(2) setTimeout執(zhí)行的函數(shù)進(jìn)入事件隊列 主線程從事件隊列讀取函數(shù)執(zhí)行 這也就是為什么即使設(shè)置setTimeout(fn, 0)函數(shù)也不會立即執(zhí)行的原因。不過即使主線程為空,0ms也是達(dá)不到的,根據(jù)HTML標(biāo)準(zhǔn),最低是4ms。

setInterval 還有一個與setTimeout類似的函數(shù),對于setInterval來說,是循環(huán)執(zhí)行。對于執(zhí)行順序來說,setInterval會每隔指定的時間將注冊的函數(shù)置入Event Queue,如果前面的任務(wù)耗時太久,那么同樣需要等待。

但是需要注意的一點是,對于setInterval(fn, ms)來說,他并不是每過ms執(zhí)行一次 ,而是每過 ms 會有fn進(jìn)入任務(wù)隊列。也就是說如果setInterval 的回調(diào)函數(shù)的執(zhí)行事件如果超過延遲ms,那么就看不出來事件間隔了。

Promise 和 process.nextTick(callback) 除了廣義的同步任務(wù)和異步任務(wù)之外,還有對任務(wù)更精細(xì)的劃分,分為:

macro-task(宏任務(wù)):包括整體代碼script、setTimeout、setInterval micro-task(微任務(wù)):Promise、process.nextTick 事件循環(huán)的順序,決定js代碼的執(zhí)行順序。進(jìn)入整體代碼(宏任務(wù))后,開始第一次循環(huán)。接著執(zhí)行所有的微任務(wù)。然后再次從宏任務(wù)開始,找到其中一個任務(wù)隊列執(zhí)行完畢,再執(zhí)行所有的微任務(wù)。

用一段代碼來說明:

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

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

console.log('4'); 這段代碼作為宏任務(wù),開始第一次循環(huán) 先遇到setTimeout,那么它的回調(diào)函數(shù)進(jìn)入到宏任務(wù)事件隊列中 遇到Promise,Promise立即執(zhí)行,輸出2,then任務(wù)進(jìn)入到微任務(wù)事件隊列中 下面遇到console,輸出4 第一個宏任務(wù)結(jié)束,看微任務(wù)事件隊列,執(zhí)行then,輸出3 第一輪循環(huán)結(jié)束,看宏任務(wù)隊列中存在setTimeout的回調(diào)函數(shù)執(zhí)行,輸出1 所有結(jié)果為:2,4,3,1 好了了解了基本的原理之后,我們來看一個更復(fù)雜的:

console.log('1');

setTimeout(function() { console.log('2'); process.nextTick(function() { console.log('3'); }) new Promise(function(resolve) { console.log('4'); resolve(); }).then(function() { console.log('5') }) }) process.nextTick(function() { console.log('6'); }) new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') })

setTimeout(function() { console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { console.log('11'); resolve(); }).then(function() { console.log('12') }) }) 不知道大家答案是什么?接下來我們來進(jìn)行分析一下:

第一輪:

首先整段代碼作為一個宏任務(wù)進(jìn)入主線程,首先遇到console.log()輸出1 遇到第一個setTimeout()進(jìn)入宏任務(wù)隊列 遇到Process.nextTick()進(jìn)入微任務(wù)隊列 然后遇到Promise,立即執(zhí)行,輸出7,then被添加到微任務(wù)隊列 遇到第二個setTimeout,進(jìn)入宏任務(wù)隊列 然后執(zhí)行兩個微任務(wù) 執(zhí)行Process.nextTick()輸出6 執(zhí)行then,輸出8 這樣第一輪循環(huán)就徹底結(jié)束了,進(jìn)行第二輪事件循環(huán),也就是第一個setTimeout

首先遇到console.log(),輸出2 遇到Process.nextTick(),進(jìn)入微任務(wù)隊列 遇到Promise立即執(zhí)行輸出4,then進(jìn)入微任務(wù)隊列 然后執(zhí)行第一個微任務(wù),輸出3 執(zhí)行then,輸出5 這樣第二輪事件循環(huán)就結(jié)束了,最后執(zhí)行第二個setTimeout,第二個setTimeout和上面原理類似,也就不重復(fù)說明了。所以最終結(jié)果是:1,7,6,8,2,4,3,5,9,11,10,12

加Java架構(gòu)師群獲取Java工程化、高性能及分布式、高性能、深入淺出。高架構(gòu)。性能調(diào)優(yōu)、Spring,MyBatis,Netty源碼分析和大數(shù)據(jù)等多個知識點高級進(jìn)階干貨的直播免費學(xué)習(xí)權(quán)限 都是大牛帶飛 讓你少走很多的彎路的 群..號是:855801563 對了 小白勿進(jìn) 最好是有開發(fā)經(jīng)驗

注:加群要求

1、具有工作經(jīng)驗的,面對目前流行的技術(shù)不知從何下手,需要突破技術(shù)瓶頸的可以加。

2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內(nèi)進(jìn)修、跳槽拿高薪的可以加。

3、如果沒有工作經(jīng)驗,但基礎(chǔ)非常扎實,對java工作機(jī)制,常用設(shè)計思想,常用java開發(fā)框架掌握熟練的,可以加。

4、覺得自己很牛B,一般需求都能搞定。但是所學(xué)的知識點沒有系統(tǒng)化,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加。

5.阿里Java高級大牛直播講解知識點,分享知識,多年工作經(jīng)驗的梳理和總結(jié),帶著大家全面、科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知!

轉(zhuǎn)載于:https://juejin.im/post/5be8108e6fb9a049ba41172d

總結(jié)

以上是生活随笔為你收集整理的彻底搞懂JavaScript执行机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。