摘要:而函數(shù)調(diào)用結(jié)束返回時(shí),運(yùn)行時(shí)會(huì)將棧頂?shù)恼{(diào)用結(jié)構(gòu)彈出。并發(fā)模型與引擎是單線程的,它的并發(fā)模型基于事件循環(huán)當(dāng)線程中的同步任務(wù)執(zhí)行完,執(zhí)行棧為空時(shí),則從任務(wù)隊(duì)列中取出異步任務(wù)進(jìn)行處理。在當(dāng)前的微任務(wù)沒有執(zhí)行完成時(shí),是不會(huì)執(zhí)行下一個(gè)宏任務(wù)的。
堆/棧/隊(duì)列
在javascript中,存在調(diào)用棧 (call stack)和內(nèi)存堆(memory heap) ,程序中函數(shù)依次進(jìn)入棧中等待執(zhí)行,若執(zhí)行時(shí)遇到異步方法,該異步方法會(huì)被添加到用于回調(diào)的任務(wù)隊(duì)列(task queue)中,【即JavaScript執(zhí)行引擎的單線程擁有一個(gè)調(diào)用棧、內(nèi)存堆和一個(gè)任務(wù)隊(duì)列】
調(diào)用棧 (call stack):CallStack是用來處理函數(shù)調(diào)用與返回的。特點(diǎn)是先進(jìn)后出,每次調(diào)用一個(gè)函數(shù),Javascript運(yùn)行時(shí)會(huì)生成一個(gè)新的調(diào)用結(jié)構(gòu)壓入CallStack。而函數(shù)調(diào)用結(jié)束返回時(shí),JavaScript運(yùn)行時(shí)會(huì)將棧頂?shù)恼{(diào)用結(jié)構(gòu)彈出。由于棧的LIFO特性,每次彈出的必然是最新調(diào)用的那個(gè)函數(shù)的結(jié)構(gòu)。函數(shù)調(diào)用會(huì)形成了一個(gè)堆棧幀,存放基本數(shù)據(jù)類型的變量并發(fā)模型 與 EventLoop內(nèi)存堆(memory head):引用數(shù)據(jù)類型被存放在堆中,在我們進(jìn)行淺復(fù)制時(shí),我們改變的只是引用數(shù)據(jù)類型在棧內(nèi)存中的引用地址,實(shí)際上它在堆內(nèi)存中的引用地址仍然沒有發(fā)生變化
任務(wù)隊(duì)列(task queue):javaScript 運(yùn)行時(shí)包含了一個(gè)待處理的任務(wù)隊(duì)列。
javascript引擎是單線程的,它的并發(fā)模型基于Event Loop(事件循環(huán))
當(dāng)線程中的同步任務(wù)執(zhí)行完,執(zhí)行棧為空時(shí),則從任務(wù)隊(duì)列(task queue)中取出異步任務(wù)進(jìn)行處理。這個(gè)處理過程包含了調(diào)用與這個(gè)任務(wù)相關(guān)聯(lián)的函數(shù)(以及因而創(chuàng)建了一個(gè)初始堆棧幀)。當(dāng)執(zhí)行棧再次為空的時(shí)候,也就意味著該任務(wù)處理結(jié)束,從任務(wù)隊(duì)列中取出下一個(gè)異步任務(wù)進(jìn)行處理,不斷重復(fù),這個(gè)過程是循環(huán)不斷的, 所以整個(gè)的這種運(yùn)行機(jī)制又稱為Event Loop(事件循環(huán)).Task Queue 任務(wù)隊(duì)列
任務(wù)隊(duì)列有宏任務(wù)隊(duì)列與微任務(wù)隊(duì)列,每次事件循環(huán)的時(shí)候,會(huì)先執(zhí)行宏任務(wù)隊(duì)列中的任務(wù),然后再執(zhí)行微任務(wù)隊(duì)列中的任務(wù)。 在當(dāng)前的微任務(wù)沒有執(zhí)行完成時(shí),是不會(huì)執(zhí)行下一個(gè)宏任務(wù)的。
宏任務(wù):script(全局任務(wù)), setTimeout, setInterval, setImmediate, I/O, UI rendering.
微任務(wù):process.nextTick, Promise, Object.observer, MutationObserver.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109524.html
摘要:需要注意的是,定時(shí)器只是將事件插入了任務(wù)隊(duì)列,必須等到當(dāng)前代碼執(zhí)行棧執(zhí)行完,主線程才會(huì)去執(zhí)行它指定的回調(diào)函數(shù)。如果當(dāng)前代碼耗時(shí)很長(zhǎng),有可能要等很久,所以并沒有辦法保證,回調(diào)函數(shù)一定會(huì)在指定的時(shí)間執(zhí)行。這也引申出的并發(fā)模型。 一、JavaScript的單線程 眾所周知,JavaScript的一大特點(diǎn)就是單線程,但是我們有沒有思考過它為什么不能是多線程的? 我們假定JavaScript有兩...
摘要:規(guī)范中定義了瀏覽器何時(shí)進(jìn)行渲染更新,了解它有助于性能優(yōu)化。結(jié)合一些資料,對(duì)上邊規(guī)范給出一些理解有誤請(qǐng)指正每個(gè)線程都有自己的。列為,列為,列為。我們都知道是單線程,渲染計(jì)算和腳本運(yùn)行共用同一線程網(wǎng)絡(luò)請(qǐng)求會(huì)有其他線程,導(dǎo)致腳本運(yùn)行會(huì)阻塞渲染。 本文轉(zhuǎn)自blog 轉(zhuǎn)載請(qǐng)注明出處 異步的思考 event loops隱藏得比較深,很多人對(duì)它很陌生。但提起異步,相信每個(gè)人都知道。異步背后的靠山就是...
摘要:回調(diào)函數(shù)任務(wù)完成的時(shí)候,需要執(zhí)行哪段代碼來處理呢當(dāng)然是回調(diào)函數(shù)了。事件處理器和回調(diào)函數(shù)類似。但是特定的事件處理器在瀏覽器進(jìn)入異步事件驅(qū)動(dòng)階段時(shí)就會(huì)針對(duì)特定的事件注冊(cè)。當(dāng)事件對(duì)象返回到執(zhí)行線程時(shí),事件處理器也會(huì)同時(shí)進(jìn)入執(zhí)行棧中執(zhí)行。 Event Loop(事件輪詢)機(jī)制是一個(gè)經(jīng)常把人搞暈的東東。我不敢說我完全明白,只是在此談?wù)勎业臏\見。 事件的處理 瀏覽器是一個(gè)事件驅(qū)動(dòng)(event-dr...
摘要:由于是單線程的,這些方法就會(huì)按順序被排列在一個(gè)單獨(dú)的地方,這個(gè)地方就是所謂執(zhí)行棧。事件隊(duì)列每次僅執(zhí)行一個(gè)任務(wù),在該任務(wù)執(zhí)行完畢之后,再執(zhí)行下一個(gè)任務(wù)。 Event Loop 是 JavaScript 異步編程的核心思想,也是前端進(jìn)階必須跨越的一關(guān)。同時(shí),它又是面試的必考點(diǎn),特別是在 Promise 出現(xiàn)之后,各種各樣的面試題層出不窮,花樣百出。這篇文章從現(xiàn)實(shí)生活中的例子入手,讓你徹底理解 E...
閱讀 2663·2023-04-26 00:07
閱讀 2443·2021-11-15 11:37
閱讀 656·2021-10-19 11:44
閱讀 2183·2021-09-22 15:56
閱讀 1740·2021-09-10 10:50
閱讀 1513·2021-08-18 10:21
閱讀 2580·2019-08-30 15:53
閱讀 1643·2019-08-30 11:11