亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Event Loop 其實(shí)也就這點(diǎn)事

PrototypeZ / 2356人閱讀

摘要:眾所周知,是,也就意味著在執(zhí)行的過(guò)程中,是,而這樣的特性,正是由一個(gè)叫的東西決定的有且僅有一個(gè)。無(wú)論從工程效率還是用戶體驗(yàn)的角度來(lái)說(shuō),這都是不被允許的一件事情。五秒后,結(jié)束計(jì)時(shí),將回調(diào)函數(shù)下放到中。至此,正式引出的概念。

前段時(shí)間在網(wǎng)上陸續(xù)看了很多關(guān)于 Event loop 的文章,看完也就混個(gè)眼熟,可能內(nèi)心深處對(duì)這種偏原理的知識(shí)有一些抵觸心情,看完后也都沒(méi)有去深入理解。最近在看 Vue 的源碼,在讀到關(guān)于 nextTick 的實(shí)現(xiàn)時(shí),總有一種似曾相識(shí)的感覺(jué),于是去網(wǎng)上查了下資料,原來(lái) nextTick 的實(shí)現(xiàn)正是基于 Event loop 機(jī)制(引起重視了)。
Anyway,在翻閱了一些資料以后,將我對(duì) Event loop 的理解記錄下來(lái),愛(ài)看不看。

Call Stack

眾所周知,JavaScript 是 one-threaded,也就意味著在執(zhí)行 JavaScript 的過(guò)程中,是 One thing at a time,而這樣的特性,正是由一個(gè)叫 Call Stack 的東西決定的(有且僅有一個(gè))。
既然是棧,就滿足 FILO 的原則。故 Call Stack 在函數(shù)運(yùn)行時(shí)的表現(xiàn)為:

當(dāng)有函數(shù)執(zhí)行時(shí),該函數(shù)被 push 到 Call Stack

當(dāng)函數(shù)執(zhí)行結(jié)束時(shí),該函數(shù)從 Call Stack 內(nèi)被 pop 出

如果函數(shù)內(nèi)有調(diào)用到其他函數(shù)(執(zhí)行結(jié)束前),則將其他函數(shù)再 push 到 Call Stack 中,等到調(diào)用結(jié)束時(shí) pop 出

由此可見(jiàn),如果一個(gè)函數(shù)定義如下:

const dead = () => {
    return dead();
}

那么當(dāng)其被執(zhí)行時(shí),就會(huì)向 Call Stack 中不斷的 push 同一個(gè)函數(shù)(dead),導(dǎo)致整個(gè)頁(yè)面掛掉。

When Call Stack Meets Sync Request

眾所又周知了,在 jQuery 提供的 Ajax 函數(shù)中,可供開(kāi)發(fā)者選擇請(qǐng)求是 sync 還是 async,我們先討論 Call Stack 遇到 sync 請(qǐng)求時(shí)會(huì)發(fā)生什么。

const name = $.ajaxSync(URL_1);
const info = $.ajaxSync(URL_2);
const work = $.ajaxSync(URL_3);

console.log(name);
console.log(info);
console.log(work);

屋漏偏逢連陰雨,此時(shí)的網(wǎng)絡(luò)狀態(tài)又極差,每一個(gè)網(wǎng)絡(luò)請(qǐng)求從發(fā)出到成功要經(jīng)歷五秒,想象一下上面這段代碼如果跑起來(lái)了,會(huì)發(fā)生什么?
這是一件讓人絕望的事情:
隨著程序的推進(jìn),ajaxSync 函數(shù)會(huì)先后三次被 push 并 pop 出 Call Stack,而每一次從 push 到 pop 的過(guò)程需要耗費(fèi)五秒鐘的時(shí)間。
無(wú)論從工程效率還是用戶體驗(yàn)的角度來(lái)說(shuō),這都是不被允許的一件事情。

Async & Callback

為了杜絕上面的問(wèn)題,瀏覽器提供給了開(kāi)發(fā)者一個(gè)叫做異步 + Callback 的解決方案。先看一段代碼:

console.log("kyrieliu");

setTimeout(function(){
    console.log("about Event Loop");
}, 5000);

console.log(" is writing an article ");

運(yùn)行結(jié)果顯而易見(jiàn)。
ok,那么這段代碼在 Call Stack 中的表現(xiàn)又是怎樣的呢?
基于上面文章所述,我推測(cè):
首先,第一行代碼入棧,執(zhí)行完畢后出棧;緊接著,setTimeout 入棧,然后emmm,事情有點(diǎn)不對(duì)勁了:如果 setTimeout 入棧執(zhí)行后立刻出棧,那么它內(nèi)部的 console 為什么五秒后才打印出來(lái)?

Task Queue

問(wèn)題的關(guān)鍵,是一個(gè)叫做 Task Queue 的東西。
緊接著剛才的步驟:setTimeout入棧后執(zhí)行并觸發(fā)了一個(gè)五秒的 timer,這個(gè) timer 由 Web api 維護(hù),至此,setTimeout執(zhí)行完畢并出棧,第三個(gè) console 入棧執(zhí)行并出棧。五秒后,timer 結(jié)束計(jì)時(shí),將回調(diào)函數(shù) callback 下放到 task queue 中。
但 callback 還未執(zhí)行,它什么時(shí)候執(zhí)行呢?Call Stack 為空的時(shí)候。
此時(shí)的 call stack 已經(jīng)為空,所以 callback 被 push 進(jìn)棧執(zhí)行并 pop 出,這樣一來(lái)就解釋得通了。
至此,正式引出 Event Loop 的概念。

Event Loop

If the call stack is clear and there"s something in the task queue, push the first thing on the queue onto the stack.

setTimeout(callback, 0)

在最開(kāi)始接觸 JavaScript 的時(shí)候,看到上面這行代碼的我是懵蔽的,0ms 后執(zhí)行 callback, WTF?
在了解了 Event Loop 的運(yùn)行機(jī)制后,再回過(guò)頭來(lái)嘗試解釋一下這行代碼,即:在 setTimeout 入棧執(zhí)行時(shí),內(nèi)部的 callback 會(huì)立即被下放到 task queue 中,但它無(wú)法執(zhí)行,因?yàn)榇藭r(shí)的 call stack 不為空,等到 call stack 為空時(shí),callback 才得以執(zhí)行。

Thanks

Philip Roberts: Help, I’m stuck in an event-loop.

A super-cool demo of Event Loop

廣而告之
個(gè)人公眾號(hào),不止于前端

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/97298.html

相關(guān)文章

  • 瀏覽器與Node的件循環(huán)(Event Loop)有何區(qū)別?

    摘要:事件觸發(fā)線程主要負(fù)責(zé)將準(zhǔn)備好的事件交給引擎線程執(zhí)行。它將不同的任務(wù)分配給不同的線程,形成一個(gè)事件循環(huán),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給引擎。 Fundebug經(jīng)作者浪里行舟授權(quán)首發(fā),未經(jīng)同意請(qǐng)勿轉(zhuǎn)載。 前言 本文我們將會(huì)介紹 JS 實(shí)現(xiàn)異步的原理,并且了解了在瀏覽器和 Node 中 Event Loop 其實(shí)是不相同的。 一、線程與進(jìn)程 1. 概念 我們經(jīng)常說(shuō) JS 是單線程執(zhí)行的,...

    TANKING 評(píng)論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問(wèn)題。上述兩個(gè)例子其實(shí)是在這個(gè)中找到的,第一個(gè)使用的版本是,這個(gè)版本的實(shí)現(xiàn)是采用了,而后因?yàn)榈睦锏挠?,于是尤雨溪更改了?shí)現(xiàn),換成了,也就是后一個(gè)所使用的。后來(lái)尤雨溪了解到是將回調(diào)放入的隊(duì)列。 結(jié)論 對(duì)于event loop 可以抽象成一段簡(jiǎn)單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    springDevBird 評(píng)論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問(wèn)題。上述兩個(gè)例子其實(shí)是在這個(gè)中找到的,第一個(gè)使用的版本是,這個(gè)版本的實(shí)現(xiàn)是采用了,而后因?yàn)榈睦锏挠?,于是尤雨溪更改了?shí)現(xiàn),換成了,也就是后一個(gè)所使用的。后來(lái)尤雨溪了解到是將回調(diào)放入的隊(duì)列。 結(jié)論 對(duì)于event loop 可以抽象成一段簡(jiǎn)單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    Barry_Ng 評(píng)論0 收藏0
  • 細(xì)說(shuō)JavaScript單線程的一些

    摘要:標(biāo)簽單線程首發(fā)地址碼農(nóng)網(wǎng)細(xì)說(shuō)單線程的一些事最近被同學(xué)問(wèn)道單線程的一些事,我竟回答不上。若以多線程的方式操作這些,則可能出現(xiàn)操作的沖突。另外,因?yàn)槭菃尉€程的,在某一時(shí)刻內(nèi)只能執(zhí)行特定的一個(gè)任務(wù),并且會(huì)阻塞其它任務(wù)執(zhí)行。 標(biāo)簽: JavaScript 單線程 首發(fā)地址:碼農(nóng)網(wǎng)《細(xì)說(shuō)JavaScript單線程的一些事》 最近被同學(xué)問(wèn)道 JavaScript 單線程的一些事,我竟回答不上。好...

    sarva 評(píng)論0 收藏0
  • 細(xì)說(shuō)JavaScript單線程的一些

    摘要:標(biāo)簽單線程首發(fā)地址碼農(nóng)網(wǎng)細(xì)說(shuō)單線程的一些事最近被同學(xué)問(wèn)道單線程的一些事,我竟回答不上。若以多線程的方式操作這些,則可能出現(xiàn)操作的沖突。另外,因?yàn)槭菃尉€程的,在某一時(shí)刻內(nèi)只能執(zhí)行特定的一個(gè)任務(wù),并且會(huì)阻塞其它任務(wù)執(zhí)行。 標(biāo)簽: JavaScript 單線程 首發(fā)地址:碼農(nóng)網(wǎng)《細(xì)說(shuō)JavaScript單線程的一些事》 最近被同學(xué)問(wèn)道 JavaScript 單線程的一些事,我竟回答不上。好...

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

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

0條評(píng)論

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