[译]理解js中的event loop
生活随笔
收集整理的這篇文章主要介紹了
[译]理解js中的event loop
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
之前看的文,感覺(jué)不太完整,于是找了篇詳細(xì)的文章原文鏈接。翻譯不正確的請(qǐng)指出,重在分享,如果有所收獲就更好了。
Javascript是如何異步和單線程的?簡(jiǎn)短的回答是javascript語(yǔ)言是單線程的,異步行為不是它的一部分,相反,它是建立在瀏覽器(或編程環(huán)境)中的核心JavaScript語(yǔ)言之上,并通過(guò)瀏覽器API訪問(wèn)。
現(xiàn)在為了得到答案,讓我寫(xiě)兩個(gè)示例代碼片段。
基本架構(gòu)
- 堆:對(duì)象在堆中分配,表示大多數(shù)非結(jié)構(gòu)化的內(nèi)存區(qū)域。
- 棧:這表示JavaScript代碼執(zhí)行提供的單個(gè)線程,函數(shù)調(diào)用形成一個(gè)棧。
- 瀏覽器或Web API是內(nèi)置在你的web瀏覽器中,能夠暴露瀏覽器和周?chē)挠?jì)算機(jī)環(huán)境中的數(shù)據(jù),并使用它執(zhí)行游泳的復(fù)雜操作。它們不是JavaScript語(yǔ)言的一部分,而是基于核心JavaScript語(yǔ)言構(gòu)建,為你的JavaScript代碼中提供額外的超能力。例如,Geolocation API提供了一些簡(jiǎn)單的JavaScript構(gòu)造,用于檢索數(shù)據(jù),所以你可以說(shuō),在Google map上繪制你的位置。在后臺(tái),瀏覽器實(shí)際上使用一些復(fù)雜的低級(jí)代碼(例如C++)與設(shè)備的GPS硬件(或者任何可用于確定位置數(shù)據(jù)的信息)進(jìn)行通信,檢索位置數(shù)據(jù),并將其返回到瀏覽器環(huán)境用來(lái)使用在你的代碼中。但同樣,這種復(fù)雜性是由API抽象出來(lái)的。
代碼片段1:迷惑心靈
function main(){console.log('A');setTimeout(function display(){ console.log('B'); },0);console.log('C'); } main(); // Output // A // C // B 復(fù)制代碼這里,我們有一個(gè)主函數(shù),它有兩個(gè)console.log:將A和C輸入到控制臺(tái)上。它們中間是一個(gè)在0ms后將B輸出到控制臺(tái)上的setTimeOut調(diào)用。
因此setTimeout(function,delayTime)中的delay參數(shù)不代表執(zhí)行函數(shù)之后的精確時(shí)間延遲。它代表最小等待時(shí)間,之后在某個(gè)時(shí)間點(diǎn)執(zhí)行該功能。
代碼片段2:深入理解
function main(){console.log('A');setTimeout(function exec(){ console.log('B'); }, 0);runWhileLoopForNSeconds(3);console.log('C'); } main(); function runWhileLoopForNSeconds(sec){let start = Date.now(), now = start;while (now - start < (sec*1000)) {now = Date.now();} } // Output // A // C // B 復(fù)制代碼- 函數(shù)runWhileLoopForNSeconds完全符合其名稱所代表的含義,它會(huì)不斷檢查從調(diào)用時(shí)間開(kāi)始經(jīng)過(guò)的時(shí)間是否等于函數(shù)參數(shù)提供的秒數(shù)。要記住的要點(diǎn)是while循環(huán)(與許多其他循環(huán)一樣)是一個(gè)阻塞語(yǔ)句,意味著它的執(zhí)行發(fā)生在調(diào)用堆棧上,并且不使用瀏覽器API。因此它會(huì)阻止所有后續(xù)語(yǔ)句,直到它執(zhí)行完成。
- 所以在上面的代碼中,即使setTimeout的延遲為0ms,但在while循環(huán)運(yùn)行3s中,exec()回調(diào)會(huì)卡在消息隊(duì)列中。只有在while循環(huán)在調(diào)用堆棧(單線程)上運(yùn)行3s完成,調(diào)用堆棧變空之后,回調(diào)exec()被推入到調(diào)用堆棧并執(zhí)行。
- 因此setTimeout()中的delay參數(shù)不保證在計(jì)時(shí)器完成延遲后開(kāi)始執(zhí)行。它是延遲部分的最短時(shí)間。
總結(jié)
以上是生活随笔為你收集整理的[译]理解js中的event loop的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Mozilla 准备让“合格” Linu
- 下一篇: javascript模块化简介