成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript 事件循環(huán)event loop

Miyang / 2898人閱讀

摘要:現(xiàn)實(shí)中是這樣的執(zhí)行結(jié)果為結(jié)果告訴我們,是單線程沒錯(cuò),不過不是逐行同步執(zhí)行。搜索了很多官方個(gè)人博客得到了一堆詞引擎主線程事件表事件隊(duì)列宏任務(wù)微任務(wù),徹底懵逼。。。以此規(guī)則不停的執(zhí)行下去就是我們所聽到的事件循環(huán)。

都知道javascript是單線程,那么問題來了,既然是單線程順序執(zhí)行,那怎么做到異步的呢?

我們理解的單線程應(yīng)該是這樣的,排著一個(gè)個(gè)來,是同步執(zhí)行。

現(xiàn)實(shí)中js是這樣的
        setTimeout(function() {
            console.log(1);
        });
        new Promise(function(resolve, reject) {
            console.log(2)
            resolve(3)
        }).then(function(val) {
            console.log(val);
        })
        console.log(4)
        //執(zhí)行結(jié)果為 2、4、3、1

結(jié)果告訴我們,js是單線程沒錯(cuò),不過不是逐行同步執(zhí)行。

那我們就來解析一下既然有異步,那順序是怎樣的?這些執(zhí)行順序規(guī)則就是理解eventLoop的要點(diǎn),繼續(xù)往下。

上圖為我錄制的chrome控制代碼臺(tái)執(zhí)行順序,雖然能看出執(zhí)行順序但我們還是懵逼的,我們不知道規(guī)則,不懂就要問。

搜索了很多官方、個(gè)人博客得到了一堆詞:js引擎、主線程、事件表、事件隊(duì)列、宏任務(wù)、微任務(wù),徹底懵逼。。。

不急不急一個(gè)個(gè)來,我們進(jìn)入刨根問底狀態(tài)

js引擎

總結(jié)一句話就是解析優(yōu)化代碼 **制定執(zhí)行規(guī)則 具體規(guī)則往下看

主線程

總結(jié)一句話執(zhí)行js引擎優(yōu)化并排列順序后的代碼

事件表(event table)

執(zhí)行代碼過程中,異步的回調(diào),例如(setTimeout,ajax回調(diào))注冊回調(diào)事件到event table

事件隊(duì)列

當(dāng)事件回調(diào)結(jié)束,事件表(event table)會(huì)將事件移入到事件隊(duì)列(event queue)

宏任務(wù)和微任務(wù)
宏任務(wù)包含的事件
事件 瀏覽器 node
I/O ? ?
setTimeout ? ?
setInterval ? ?
setImmediate ? ?
requestAnimationFrame ? ?
微任務(wù)包含的事件
事件 瀏覽器 node
I/O ? ?
process.nextTick ? ?
MutationObserver ? ?
Promise.then catch finally ? ?

很多博客是這樣說的:
瀏覽器會(huì)不斷從task隊(duì)列中按順序取task執(zhí)行,每執(zhí)行完一個(gè)task都會(huì)檢查microtask隊(duì)列是否為空(執(zhí)行完一個(gè)task的具體標(biāo)志是函數(shù)執(zhí)行棧為空),如果不為空則會(huì)一次性執(zhí)行完所有microtask。然后再進(jìn)入下一個(gè)循環(huán)去task隊(duì)列中取下一個(gè)task執(zhí)行

說實(shí)話不是太理解,那么我就以自己的方式去學(xué)習(xí)和理解

為了更好的理解我們再看代碼

        console.log("1");
        setTimeout(function() {
            console.log("2");
            new Promise(function(resolve) {
                console.log("3");
                resolve();
            }).then(function() {
                console.log("4")
            })
        })
        new Promise(function(resolve) {
            console.log("5");
            resolve();
        }).then(function() {
            console.log("6")
        })

        setTimeout(function() {
            console.log("7");
            new Promise(function(resolve) {
                console.log("8");
                resolve();
            }).then(function() {
                console.log("9")
            })
        })
        //執(zhí)行結(jié)果:1、5、6、2、3、4、7、8、9


有圖為證我沒騙你
再來個(gè)動(dòng)圖我們具體看看瀏覽器的執(zhí)行順序

首先js引擎,區(qū)分是直接執(zhí)行(同步代碼),再執(zhí)行異步代碼,如果是異步再區(qū)分是宏任務(wù)還是微任務(wù),分別放入兩個(gè)任務(wù)隊(duì)列,然后開始執(zhí)行,每執(zhí)行完一個(gè)宏任務(wù),掃一遍微任務(wù)隊(duì)列并全部執(zhí)行,此時(shí)形成一次eventLoop循環(huán)。以此規(guī)則不停的執(zhí)行下去就是我們所聽到的事件循環(huán)。

我再補(bǔ)充一點(diǎn),可以理解js引擎一開始把整個(gè)script當(dāng)做一個(gè)宏任務(wù),這樣里邊的就更容易理解了,開始就執(zhí)行script宏任務(wù),解析到宏任務(wù)里邊又包含同步代碼和異步代碼(宏任務(wù)和微任務(wù))依次執(zhí)行順序形成eventLoop。

歡迎吐槽點(diǎn)贊評(píng)論!

文章參考學(xué)習(xí):
https://www.jianshu.com/p/12b...
https://juejin.im/post/59e85e...
https://segmentfault.com/a/11...

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/101063.html

相關(guān)文章

  • 初窺JavaScript事件機(jī)制的實(shí)現(xiàn)(一)—— Node.js事件驅(qū)動(dòng)實(shí)現(xiàn)概覽

    摘要:如果當(dāng)前沒有事件也沒有定時(shí)器事件,則返回。相關(guān)資料關(guān)于的架構(gòu)及設(shè)計(jì)思路的事件討論了使用線程池異步運(yùn)行代碼。下一篇初窺事件機(jī)制的實(shí)現(xiàn)二中定時(shí)器的實(shí)現(xiàn) 在瀏覽器中,事件作為一個(gè)極為重要的機(jī)制,給予JavaScript響應(yīng)用戶操作與DOM變化的能力;在Node.js中,事件驅(qū)動(dòng)模型則是其高并發(fā)能力的基礎(chǔ)。 學(xué)習(xí)JavaScript也需要了解它的運(yùn)行平臺(tái),為了更好的理解JavaScript的事...

    lavor 評(píng)論0 收藏0
  • JavaScript 事件循環(huán)(譯文JavaScript Event Loop

    摘要:事件循環(huán)了解了在引擎中是如何工作了之后,來看下如何使用異步回調(diào)函數(shù)來避免代碼。從回調(diào)函數(shù)被放入后秒鐘,把移到中。由于事件循環(huán)持續(xù)地監(jiān)測調(diào)用棧是否已空,此時(shí)它一注意到調(diào)用??樟?,就調(diào)用并創(chuàng)建一個(gè)新的調(diào)用棧。 聽多了JavaScript單線程,異步,V8,便會(huì)很想去知道JavaScript是如何利用單線程來實(shí)現(xiàn)所謂的異步的。我參考了一些文章,了解到一個(gè)很重要的詞匯:事件循環(huán)(Event L...

    K_B_Z 評(píng)論0 收藏0
  • JavaScript Event loop 事件循環(huán)

    摘要:階段有兩個(gè)主要功能也會(huì)執(zhí)行時(shí)間定時(shí)器到達(dá)期望時(shí)間的回調(diào)函數(shù)執(zhí)行事件循環(huán)列表里的函數(shù)當(dāng)進(jìn)入階段并且沒有其余的定時(shí)器,那么如果事件循環(huán)列表不為空,則迭代同步的執(zhí)行隊(duì)列中的函數(shù)。如果沒有,則等待回調(diào)函數(shù)進(jìn)入隊(duì)列并立即執(zhí)行。 Event Loop 本文以 Node.js 為例,講解 Event Loop 在 Node.js 的實(shí)現(xiàn),原文,JavaScript 中的實(shí)現(xiàn)大同小異。 什么是 Eve...

    luckyyulin 評(píng)論0 收藏0
  • 關(guān)于瀏覽器Event Loop

    摘要:的宿主最開始本身就是瀏覽器,處理用戶的交互事件。既然是單線程的,那就意味著任務(wù)需要排隊(duì),只有前一個(gè)任務(wù)執(zhí)行完畢,下一個(gè)任務(wù)才能開始,于是就有了任務(wù)隊(duì)列。事件循環(huán)有兩種用于瀏覽上下文的事件循環(huán)和用于的事件循環(huán)。 最近看到Event Loop這個(gè)詞出現(xiàn)的頻率有點(diǎn)高,于是查閱各方資料在此記錄一下。 先不說概念,我們來看段代碼: console.log(script start); setT...

    youkede 評(píng)論0 收藏0
  • JS異步詳解 - 瀏覽器/Node/事件循環(huán)/消息隊(duì)列/宏任務(wù)/微任務(wù)

    js異步歷史 一個(gè) JavaScript 引擎會(huì)常駐于內(nèi)存中,它等待著我們把JavaScript 代碼或者函數(shù)傳遞給它執(zhí)行 在 ES3 和更早的版本中,JavaScript 本身還沒有異步執(zhí)行代碼的能力,引擎就把代碼直接順次執(zhí)行了,異步任務(wù)都是宿主環(huán)境(瀏覽器)發(fā)起的(setTimeout、AJAX等)。 在 ES5 之后,JavaScript 引入了 Promise,這樣,不需要瀏覽器的安排,J...

    awesome23 評(píng)論0 收藏0
  • JavaScript執(zhí)行機(jī)制、事件循環(huán)

    摘要:曾經(jīng)的理解首先,是單線程語言,也就意味著同一個(gè)時(shí)間只能做一件事,那么為什么不是多線程呢這樣還能提高效率啊假定同時(shí)有兩個(gè)線程,一個(gè)線程在某個(gè)節(jié)點(diǎn)上編輯了內(nèi)容,而另一個(gè)線程刪除了這個(gè)節(jié)點(diǎn),這時(shí)瀏覽器就很懵逼了,到底以執(zhí)行哪個(gè)操作呢所以,設(shè)計(jì)者把 Event Loop曾經(jīng)的理解 首先,JS是單線程語言,也就意味著同一個(gè)時(shí)間只能做一件事,那么 為什么JavaScript不是多線程呢?這樣還能提...

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

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

0條評(píng)論

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