在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    JS 中的 Event Loop 是什么?

    大家好,我是前端西瓜哥,今天來(lái)認(rèn)識(shí)一下什么是 Event Loop。

    Event Loop,簡(jiǎn)單翻譯就是 事件循環(huán),是 JS 語(yǔ)言下實(shí)現(xiàn)運(yùn)行時(shí)的一個(gè)機(jī)制。

    JS 的異步并不像其他語(yǔ)言(比如 Java)的異步那樣可以實(shí)現(xiàn)真正的并發(fā)執(zhí)行,本身其實(shí)是個(gè)單線程。

    JS 是維護(hù)了一個(gè) 任務(wù)隊(duì)列,每當(dāng)要執(zhí)行一些異步任務(wù),比如定時(shí)器或者是點(diǎn)擊按鈕觸發(fā)的事件響應(yīng)函數(shù)。它們不會(huì)立即執(zhí)行,而是放到這個(gè)隊(duì)列里,等待已經(jīng)在排隊(duì)的其他任務(wù)先執(zhí)行完,才輪到它們。

    隊(duì)列是一個(gè)操作受限的有序列表,表現(xiàn)為為先進(jìn)入的元素必須先出去,即 “先進(jìn)先出”,很像排隊(duì)的感覺(jué)。

    不過(guò)也有一些特殊的隊(duì)列,比如優(yōu)先級(jí)隊(duì)列,它是優(yōu)先級(jí)高的元素先出隊(duì)。

    之所以叫 Event Loop,因?yàn)樗倪壿嬁梢悦枋鰹橄旅?span id="ta8rkhc" class="wpcom_tag_link">代碼

    while?(queue.waitForMessage())?{??queue.processNextMessage();}

    當(dāng)一個(gè)任務(wù)被完成后,隊(duì)列會(huì)變成等待下一個(gè)任務(wù)狀態(tài),然后處理下一個(gè)任務(wù),如此循環(huán)往復(fù)。

    因?yàn)?JS 的代碼執(zhí)行本身是一個(gè)單線程,為了不讓執(zhí)行阻塞,JS 會(huì)把網(wǎng)絡(luò)請(qǐng)求操作、渲染瀏覽器頁(yè)面等操作,交給其他的線程,等待其他線程處理好把結(jié)果返回給 JS。

    所以 JS 不合適 CPU 密集型,更適合 IO 密集型的場(chǎng)景。因?yàn)樗挥幸粋€(gè)線程,如果計(jì)算耗時(shí)太長(zhǎng),就會(huì)阻塞其他要執(zhí)行的任務(wù),導(dǎo)致卡頓,甚至崩潰。

    setTimeout 定時(shí)器并不準(zhǔn)

    setTimeout 在特定時(shí)間后要執(zhí)行的函數(shù),并不會(huì)立即執(zhí)行,而是會(huì)先放到任務(wù)隊(duì)列中,先等待前面的任務(wù)同步執(zhí)行完成了,才能執(zhí)行我們這個(gè)。

    下面看一個(gè)例子,因?yàn)榈谝粋€(gè) setTimout 有一個(gè)非常耗時(shí)的同步任務(wù),導(dǎo)致下一個(gè) setTimeout 的執(zhí)行阻塞,比前面一個(gè) setTimeout 執(zhí)行要慢半秒。

    const?start?=?new?Date().getTime();setTimeout(()?=>?{??console.log(‘1:’,?new?Date().getTime()?–?start);??let?num?=?0;??for?(let?i?=?0;?i??{??console.log(‘2:’,?new?Date().getTime()?–?start);},?1000);/**?*?輸出結(jié)果:?*?1:?1001?*?2:?1505?*/

    定時(shí)器的時(shí)間,指的是能執(zhí)行的最早時(shí)間,但不能保證一定能在這個(gè)時(shí)間點(diǎn)立即執(zhí)行。

    宏任務(wù)和微任務(wù)

    任務(wù)隊(duì)列并不是嚴(yán)格意義上的先進(jìn)先出的正常隊(duì)列,是可以調(diào)整執(zhí)行順序的。

    我們將要執(zhí)行的任務(wù)分為宏任務(wù)和微任務(wù),其中宏任務(wù)是正常的先進(jìn)先出,而微任務(wù)則是可以插隊(duì),優(yōu)先于宏任務(wù)先執(zhí)行。宏任務(wù)必須在所有微任務(wù)執(zhí)行后才能執(zhí)行。

    當(dāng)我們給任務(wù)隊(duì)列添加一個(gè)微任務(wù)時(shí),它會(huì)跑到任務(wù)隊(duì)列宏任務(wù)前。多個(gè)微任務(wù)入隊(duì)時(shí),會(huì)保持它們的相對(duì)順序。

    宏任務(wù)有:

    • script,即 HTML 嵌入的腳本;
    • setTimeout / setInterval 定時(shí)器;
    • setImmediate,這是 nodejs 特有的 API;
    • requestAnimationFrame,會(huì)在頁(yè)面重繪前執(zhí)行;
    • I/O 操作,比如網(wǎng)絡(luò)請(qǐng)求完成的回調(diào)函數(shù)執(zhí)行任務(wù)、還比如點(diǎn)擊按鈕要執(zhí)行的回調(diào)等。這些操作其實(shí)是其他的線程完成后觸發(fā)的,暫且歸納為 I/O 操作。

    微任務(wù)有:

    • Promise 從 pending 狀態(tài)轉(zhuǎn)換為其他狀態(tài)時(shí),觸發(fā) then/catch/finaly 中的函數(shù),比如 Promise.resolve().then(fn)。這是最常見(jiàn)的微任務(wù)。
    • MutationObserver,用于監(jiān)聽(tīng) DOM 的變化
    • process.nextTick,nodejs 特有的 API

    任務(wù)隊(duì)列,理論上一個(gè)就夠了,但也可以是多個(gè)隊(duì)列的組合,沒(méi)有強(qiáng)行要求。

    多個(gè)任務(wù)隊(duì)列的實(shí)現(xiàn)可以更好地實(shí)現(xiàn)優(yōu)先級(jí)的控制,比如對(duì)于定時(shí)器任務(wù),理論上應(yīng)該是在多個(gè)宏任務(wù)中最先執(zhí)行比較好。瀏覽器沒(méi)考慮這種情況,但 nodejs 給宏任務(wù)中也設(shè)置優(yōu)先級(jí),會(huì)讓定時(shí)器任務(wù)最先執(zhí)行。

    Event Loop 還是挺復(fù)雜的,標(biāo)準(zhǔn)文檔也比較長(zhǎng),我也沒(méi)怎么看,感興趣可以看看。

    https://html.spec.whatwg.org/multipage/webappapis.html#event-loops

    一道經(jīng)典異步題

    async?function?async1()?{??console.log(“async1?start”);??await?async2();??console.log(“async1?end”);}async?function?async2()?{??console.log(“async2”);}console.log(“script?start”);setTimeout(function()?{??console.log(“setTimeout”);},?0);async1();new?Promise(function(resolve)?{??console.log(“promise1”);??resolve();}).then(function()?{??console.log(“promise2”);});console.log(‘script?end’)

    解題思路為:

    • 找到同步代碼。同步代碼有:普通同步代碼、new Promise(fn) 執(zhí)行傳入的回調(diào)函數(shù)、async 執(zhí)行時(shí)遇到 await 的前面部分(包括 await 的右側(cè)函數(shù)執(zhí)行也是同步的,這里是易錯(cuò)點(diǎn))。
    • 看看任務(wù)隊(duì)列中有哪些微任務(wù)和宏任務(wù),記住微任務(wù)全執(zhí)行完了才會(huì)執(zhí)行宏任務(wù)。
    • 執(zhí)行任務(wù),任務(wù)里面的異步任務(wù)又按順序進(jìn)入到任務(wù)隊(duì)列。

    結(jié)果是:

    // 同步代碼script startasync1 startasync2promise1script end// 微任務(wù)async1 endpromise2// 宏任務(wù)setTimeout

    結(jié)尾

    JS 運(yùn)行機(jī)制是單線程,當(dāng)有多個(gè)異步任務(wù)要同時(shí)執(zhí)行,并不能并發(fā)執(zhí)行,必須讓優(yōu)先級(jí)高的任務(wù)執(zhí)行完才能執(zhí)行后面的。如果正在執(zhí)行的任務(wù)比較耗時(shí),會(huì)導(dǎo)致后面的任務(wù)被阻塞。

    Event Loop 的機(jī)制中,最基本的一條就是:微任務(wù)比宏任務(wù)先執(zhí)行。

    我是前端西瓜哥,歡迎關(guān)注我,一起學(xué)習(xí)前端技術(shù)。

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年6月21日 15:15
    下一篇 2022年6月21日 15:15

    相關(guān)推薦

    • 存儲(chǔ)過(guò)程語(yǔ)法(sql server存儲(chǔ)過(guò)程語(yǔ)法)

      今天小編給各位分享存儲(chǔ)過(guò)程語(yǔ)法的知識(shí),其中也會(huì)對(duì)sql server存儲(chǔ)過(guò)程語(yǔ)法進(jìn)行解釋?zhuān)绻芘銮山鉀Q你現(xiàn)在面臨的問(wèn)題,別忘了關(guān)注本站,現(xiàn)在開(kāi)始吧! oracle存儲(chǔ)過(guò)程基本語(yǔ)法…

      2022年11月26日
    • 寶可夢(mèng)朱紫寶主順序怎么選擇?寶可夢(mèng)朱紫寶主挑戰(zhàn)順序攻略

      寶可夢(mèng)朱紫寶主順序如何選擇?寶主挑戰(zhàn)的順序有很多玩家都加入了討論,大家想要了解清楚正確的挑戰(zhàn)順序,接下來(lái)小編就給大家簡(jiǎn)單的介紹一下寶主挑戰(zhàn)的順序,各位趕緊通過(guò)下面的攻略多了解一下詳…

      2022年11月25日
    • 5+3疫情防控從哪天開(kāi)始算(遼寧疫情防控最新政策)

      最近有關(guān)國(guó)內(nèi)各地的疫情大家也都有在持續(xù)關(guān)注,目前國(guó)內(nèi)各地疫情隔離時(shí)間也根據(jù)二十條防控措施有了新的調(diào)整。那么,5+3疫情防控從哪天開(kāi)始算?對(duì)于密接的5+3隔離時(shí)間計(jì)算大家還是比較關(guān)心…

      2022年11月25日
    • 藍(lán)碼怎么變綠碼需要幾天(藍(lán)碼怎么變綠碼需要幾天)

      大家都知道健康碼的顏色有紅碼、綠碼、黃碼,近日湖南健康碼上線“藍(lán)碼”,不少小伙伴發(fā)現(xiàn)自己健康碼變藍(lán)了,都想趕緊恢復(fù)綠碼,那么藍(lán)碼怎么變綠碼需要幾天?下面小編為大家?guī)?lái)藍(lán)碼變綠碼需要…

      2022年11月25日
    • 拼多多百億補(bǔ)貼預(yù)售一般多久發(fā)貨(拼多多百億補(bǔ)貼預(yù)售)

      拼多多里面有很多優(yōu)惠活動(dòng),其中百億補(bǔ)貼活動(dòng)非?;鸨?,一些里面的東西價(jià)格比別的平臺(tái)便宜,質(zhì)量也有保障,還有預(yù)售的活動(dòng),那么拼多多百億補(bǔ)貼預(yù)售一般多久發(fā)貨?下面小編為大家?guī)?lái)拼多多百億…

      2022年11月25日
    • 北京疫情多久能解除封控(北京疫情還要多久結(jié)束)

      最近一段時(shí)間北京疫情形勢(shì)備受關(guān)注,馬上就要到年底了,不少人想要去北京辦事,。都非常關(guān)注當(dāng)?shù)匾咔橄嚓P(guān)政策,那么 北京疫情多久能解除封控?北京疫情什么時(shí)候恢復(fù)正常生活?下面小編為大家?guī)А?/p>

      2022年11月25日
    • 淘寶直播開(kāi)通后帶貨鏈接怎么做(淘寶直播需要開(kāi)通淘寶店鋪嗎)

      直播帶貨無(wú)論是對(duì)于商家來(lái)說(shuō)還是主播收益都是非??捎^的,所以不少平臺(tái)都有直播帶貨功能,一些小伙伴也想加入淘寶直播,那么淘寶直播開(kāi)通后帶貨鏈接怎么做?下面小編為大家?guī)?lái)淘寶直播開(kāi)通后帶…

      2022年11月24日
    • cpu性能天梯圖2022 AMD CPU天梯圖最新排行榜出爐

      用戶在DIY自己的主機(jī)時(shí)選擇CPU是非常關(guān)鍵的,CPU可以說(shuō)是電腦的大腦,大家也都想追求好一點(diǎn)的CPU來(lái)使用,但型號(hào)太多了,大部分的用戶都不知道目前哪一款CPU比較好用,快來(lái)看看詳…

      2022年11月24日
    • 寶可夢(mèng)朱紫道館及寶主攻略順序是什么 道館及寶主攻略順序匯總

      作為寶可夢(mèng)資深?lèi)?ài)好者,小伙伴們對(duì)寶可夢(mèng)朱紫里面的所有道館恨不得馬上跳過(guò),當(dāng)場(chǎng)就來(lái)挑戰(zhàn)地區(qū)冠軍,但這顯然是不可能的,你得按照游戲里面遇到的順序來(lái)進(jìn)行挑戰(zhàn)。那么具體的挑戰(zhàn)順序是什么樣的…

      2022年11月24日
    • 《英雄聯(lián)盟》雙城之戰(zhàn)一周年活動(dòng)是什么?雙城之戰(zhàn)一周年活動(dòng)一覽

      近期距英雄聯(lián)盟雙城之戰(zhàn)上線已經(jīng)一周年時(shí)間了,官方也推出了慶雙城之戰(zhàn)一周年活動(dòng),今天小編給大家?guī)?lái)lol雙城之戰(zhàn)一周年活動(dòng)一覽,感興趣的小伙伴快來(lái)看一下吧。 雙城之戰(zhàn)一周年活動(dòng)一覽 …

      2022年11月23日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息