国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js的執(zhí)行機(jī)制

guyan0319 / 1315人閱讀

摘要:異步執(zhí)行機(jī)制異步執(zhí)行相對(duì)來說復(fù)雜些所以詳細(xì)描述下關(guān)鍵是在各種使用情況下執(zhí)行順序問題在此就需要引入一個(gè)概念。在達(dá)到這個(gè)下限時(shí)間后執(zhí)行和這些定時(shí)器設(shè)定的回調(diào)。執(zhí)行設(shè)定的回調(diào)。

js在哪執(zhí)行

js的執(zhí)行引擎基于v8(c++編寫),在chrome和node中都有應(yīng)用,執(zhí)行時(shí)有以下兩部分構(gòu)成

內(nèi)存堆(內(nèi)存分配)

調(diào)用棧(代碼執(zhí)行)

上述兩部分的聯(lián)系就是代碼在調(diào)用棧中執(zhí)行,執(zhí)行過程中會(huì)存取一些對(duì)象在內(nèi)存堆上。

我們寫的js代碼經(jīng)過js引擎(解釋器)轉(zhuǎn)化為高效的機(jī)器碼,現(xiàn)在的v8引擎由TurboFan和Ignition兩部分構(gòu)成,其中Ignition是解釋器,而TurboFan主要對(duì)代碼做些優(yōu)化,以提高執(zhí)行性能。

基于執(zhí)行引擎的執(zhí)行原理在代碼層面我們可以做些優(yōu)化,可以參考我之前的一篇文章

js如何執(zhí)行 js同步執(zhí)行

js按照代碼順序執(zhí)行,在棧上分配執(zhí)行空間,按照調(diào)用順序,會(huì)有出棧入棧等各種情況,比較好分析,唯一值的說的地方就是js只有一個(gè)主線程,??臻g有限,如果遞歸執(zhí)行過深會(huì)發(fā)生溢出,所以在編寫代碼層面需要注意這種情況。

js異步執(zhí)行 為什么要有異步?

同步單線程代碼處理起來方便,代碼表達(dá)也容易,更符合我們的思維方式,為什么還會(huì)出現(xiàn)異步呢?
因?yàn)橥綍?huì)發(fā)生阻塞,在現(xiàn)在這個(gè)高并發(fā)時(shí)代,不能很好的處理海量請(qǐng)求,同時(shí)也不能充分利用硬件資源(想想cpu和io之間處理速度差異你就深有體會(huì))。
但是為什么不多線程呢,例如java,主要是單個(gè)線程上運(yùn)行代碼相對(duì)來多線程來說說容易寫,不必考慮在多線程環(huán)境中出現(xiàn)的復(fù)雜場(chǎng)景,例如死鎖等等。

異步執(zhí)行機(jī)制?

異步執(zhí)行相對(duì)來說復(fù)雜些,所以詳細(xì)描述下,關(guān)鍵是在各種使用情況下執(zhí)行順序問題,在此就需要引入一個(gè)概念-->Event Loop。結(jié)合下面這幅圖進(jìn)行大致說明下:

    Event Loop的概念

所有任務(wù)在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack),上圖stack區(qū)域所示。

執(zhí)行過程中可能會(huì)調(diào)用異步api,其中Background Threads負(fù)責(zé)具體異步任務(wù)執(zhí)行,結(jié)束后將宏任務(wù)回調(diào)邏輯放入task queue中,微任務(wù)回調(diào)邏輯放入micro task隊(duì)列中。

主線程執(zhí)行完畢,檢查microtask隊(duì)列是否為空,會(huì)執(zhí)行到隊(duì)列空為止

從宏任務(wù)隊(duì)列中取出一個(gè)在執(zhí)行,執(zhí)行完后,檢查并取出執(zhí)行microtask隊(duì)列的任務(wù),然后不斷重復(fù)這個(gè)步驟,對(duì)于這整個(gè)循環(huán)過程,一個(gè)對(duì)應(yīng)的描述名詞就叫做event loop。

node中異步

異步任務(wù)分類

macrotask類型包括 script整體代碼,setTimeout,setInterval,setImmediate,I/O……

microtask類型包括 Promise process.nextTick Object.observe MutaionObserver……

node中event loop各個(gè)階段的操作如下圖所示


說明,上圖中每個(gè)盒子表示了event loop的一個(gè)階段,每個(gè)階段執(zhí)行完畢后,或者執(zhí)行的回調(diào)數(shù)量達(dá)到上限后,event loop會(huì)進(jìn)入下個(gè)階段。

timers: 在達(dá)到這個(gè)下限時(shí)間后執(zhí)行setTimeout()和setInterval()這些定時(shí)器設(shè)定的回調(diào)。
I/O callbacks: 執(zhí)行除了close回調(diào),timer的回調(diào),和setImmediate()的回調(diào),例如操作系統(tǒng)回調(diào)tcp錯(cuò)誤。
idle, prepare: 僅內(nèi)部使用。
poll: 獲取新的I/O事件,例如socket的讀寫事件;node會(huì)在適當(dāng)條件下阻塞在這里,如果poll階段空閑,才會(huì)進(jìn)入下一階段。
check: 執(zhí)行setImmediate()設(shè)定的回調(diào)。
close callbacks: 執(zhí)行比如socket.on("close", ...)的回調(diào)。

下面結(jié)合一些具體例子進(jìn)行說明

require("fs").readFile("./case1.js", () => {
    setTimeout(() => {
        console.log("setTimeout in poll phase");
    });
    setImmediate(() => {
        console.log("setImmediate in poll phase");
    });
});
輸出結(jié)果是:
setImmediate in poll phase
setTimeout in poll phase
Process finished with exit code 0

說明 setImmediate的回調(diào)永遠(yuǎn)先執(zhí)行,因?yàn)閞eadFile的回調(diào)執(zhí)行是在 poll 階段,所以接下來的 check 階段會(huì)先執(zhí)行 setImmediate 的回調(diào)。

setTimeout(() => console.log("setTimeout1"), 1000);
setTimeout(() => {
    console.log("setTimeout2");
    process.nextTick(() => console.log("nextTick1"));
}, 0);
setTimeout(() => console.log("setTimeout3"), 0);

process.nextTick(() => console.log("nextTick2"));
process.nextTick(() => {
    process.nextTick(console.log.bind(console, "nextTick3"));
});
 Promise.resolve("xxx").then(() => {
    console.log("promise");
    testPromise();
});
process.nextTick(() => console.log("nextTick4"));

結(jié)果是:

nextTick2
nextTick4
nextTick3
promise
setTimeout2
setTimeout3
nextTick1
setTimeout1

在描述什么是event loop中,大概描述了microtask機(jī)制,但具體到nextTick比較特別,有一個(gè)Tick-Task-Queue專門用于存放process.nextTick的任務(wù),且有調(diào)用深度限制,上限是1000。js引擎執(zhí)行 Macro Task 任務(wù)結(jié)束后,會(huì)先遍歷執(zhí)行Tick-Task-Queue的所有任務(wù),緊接著再遍歷 Micro Task Queue 的所有任務(wù)。具體執(zhí)行邏輯可以下面代碼表示。

for (macroTask of macroTaskQueue) {

    // 1. Handle current MACRO-TASK
    handleMacroTask();

    // 2. Handle all NEXT-TICK
    for (nextTick of nextTickQueue) {
        handleNextTick(nextTick);
    }

    // 3. Handle all MICRO-TASK
    for (microTask of microTaskQueue) {
        handleMicroTask(microTask);
    }
}

所以才會(huì)先輸出process.nextTick然后才會(huì)是promise,其它的輸出順序不在贅述,前面講event-loop機(jī)制時(shí)已經(jīng)說明了。根據(jù)上面代碼表述的執(zhí)行邏輯,很顯然可以得到下面的個(gè)結(jié)論,當(dāng)遞歸調(diào)用時(shí)會(huì)發(fā)生死循環(huán),而宏任務(wù)就不會(huì)。

testPromise();
function testPromise() {
    promise = Promise.resolve("xxx").then(() => {
        console.log("promise");
        testPromise();
    });
}
//將之前步驟的promise任務(wù)換成這個(gè),setTimeout2以及之后的輸出永遠(yuǎn)沒機(jī)會(huì)出來,類比到nextTick也是這種效果

看了一些書,參考了很多資料,將自己學(xué)習(xí)的東西,理解后在輸出,希望大家辯證的看待,有空的話接下來研究一下源碼,畢竟通過demo驗(yàn)證結(jié)論的說服力沒有源碼來的那么直接。

參考鏈接
https://jakearchibald.com/201...
https://blog.sessionstack.com...
https://cnodejs.org/topic/592...
https://developer.mozilla.org...
https://nodejs.org/en/docs/gu...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92633.html

相關(guān)文章

  • 10分鐘理解JS引擎執(zhí)行機(jī)制

    摘要:深入理解引擎的執(zhí)行機(jī)制靈魂三問為什么是單線程的為什么需要異步單線程又是如何實(shí)現(xiàn)異步的呢中的中的說說首先請(qǐng)牢記點(diǎn)是單線程語言的是的執(zhí)行機(jī)制。 深入理解JS引擎的執(zhí)行機(jī)制 1.靈魂三問 : JS為什么是單線程的? 為什么需要異步? 單線程又是如何實(shí)現(xiàn)異步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.說說setTimeout 首先,請(qǐng)牢記2...

    zzbo 評(píng)論0 收藏0
  • 深入理解js引擎執(zhí)行機(jī)制

    摘要:深入理解引擎的執(zhí)行機(jī)制最近在反省,很多知識(shí)都是只會(huì)用,不理解底層的知識(shí)。在閱讀之前,請(qǐng)先記住兩點(diǎn)是單線程語言的是的執(zhí)行機(jī)制。所以,是存在異步執(zhí)行的,比如單線程是怎么實(shí)現(xiàn)異步的場(chǎng)景描述通過事件循環(huán),所以說,理解了機(jī)制,也就理解了的執(zhí)行機(jī)制啦。 深入理解js引擎的執(zhí)行機(jī)制 最近在反省,很多知識(shí)都是只會(huì)用,不理解底層的知識(shí)。所以在開發(fā)過程中遇到一些奇怪的比較難解決的bug,在思考的時(shí)候就會(huì)收...

    feng409 評(píng)論0 收藏0
  • 前端進(jìn)階系列(八):JS執(zhí)行機(jī)制

    摘要:一直以來,對(duì)的執(zhí)行機(jī)制都是模棱兩可,知道今天看了文章這一次,徹底弄懂執(zhí)行機(jī)制和的規(guī)范和實(shí)現(xiàn),才對(duì)的執(zhí)行機(jī)制有了深入的理解,下面是我的學(xué)習(xí)總結(jié)。個(gè)要點(diǎn)是單線程語言是的執(zhí)行機(jī)制,為了實(shí)現(xiàn)主線程的不阻塞,就這么誕生了。 一直以來,對(duì)JS的執(zhí)行機(jī)制都是模棱兩可,知道今天看了文章—《這一次,徹底弄懂JavaScript執(zhí)行機(jī)制》和《Event Loop的規(guī)范和實(shí)現(xiàn)》,才對(duì)JS的執(zhí)行機(jī)制有了深入的...

    JackJiang 評(píng)論0 收藏0
  • Event Loop - JS執(zhí)行機(jī)制

    摘要:心塞塞根據(jù)規(guī)范,事件循環(huán)是通過任務(wù)隊(duì)列的機(jī)制來進(jìn)行協(xié)調(diào)的。等便是任務(wù)源,而進(jìn)入任務(wù)隊(duì)列的是他們指定的具體執(zhí)行任務(wù)回調(diào)函數(shù)。然后當(dāng)前本輪的結(jié)束,主線程可以繼續(xù)取下一個(gè)執(zhí)行。 依然是:經(jīng)濟(jì)基礎(chǔ)決定上層建筑。 說明 首先,旨在搞清常用的同步異步執(zhí)行機(jī)制 其次,暫時(shí)不討論node.js的Event Loop執(zhí)行機(jī)制,以下關(guān)于瀏覽器的Event Loop執(zhí)行機(jī)制 最后,借鑒了很多前輩的研究文...

    muddyway 評(píng)論0 收藏0
  • Javascript系列之javascript機(jī)制

    摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊(duì)列回到執(zhí)行棧,回調(diào)函數(shù)就會(huì)執(zhí)行。事件循環(huán)主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制https://zhuanlan.zhihu.com/p/...從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制...

    13651657101 評(píng)論0 收藏0
  • JS執(zhí)行機(jī)制

    摘要:事件表每次調(diào)用函數(shù)或執(zhí)行異步操作時(shí),都會(huì)將其添加到事件表中,事件表負(fù)責(zé)記錄每個(gè)事件完成后執(zhí)行的回調(diào)函數(shù),并監(jiān)聽事件,事件完成后會(huì)把事件的回調(diào)函數(shù)發(fā)送到事件隊(duì)列。事件隊(duì)列事件隊(duì)列接收來自事件表的回調(diào)函數(shù),并根據(jù)順序執(zhí)行。 前言 先上一段代碼,可以根據(jù)自己之前對(duì)JS執(zhí)行機(jī)制的理解,進(jìn)行分析 console.log(script start); setTimeout(function() ...

    wow_worktile 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<