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

資訊專欄INFORMATION COLUMN

事件循環(huán)

imingyu / 1981人閱讀

摘要:所以一切版的多線程都是用單線程模擬出來的,一切多線程都是紙老虎事件循環(huán)既然是單線程,那就像只有一個窗口的銀行,客戶需要排隊一個一個辦理業(yè)務(wù),同理任務(wù)也要一個一個順序執(zhí)行。

1、關(guān)于javascript
javascript是一門 單線程 語言,在最新的HTML5中提出了Web-Worker,但javascript是單線程這一核心仍未改變。所以一切javascript版的"多線程"都是用單線程模擬出來的,一切javascript多線程都是紙老虎!
2、javascript事件循環(huán)
既然js是單線程,那就像只有一個窗口的銀行,客戶需要排隊一個一個辦理業(yè)務(wù),同理js任務(wù)也要一個一個順序執(zhí)行。如果一個任務(wù)耗時過長,那么后一個任務(wù)也必須等著。那么問題來了,假如我們想瀏覽新聞,但是新聞包含的超清圖片加載很慢,難道我們的網(wǎng)頁要一直卡著直到圖片完全顯示出來?因此聰明的程序員將任務(wù)分為兩類:

JS分為同步任務(wù)和異步任務(wù)
同步任務(wù)都在主線程上執(zhí)行,形成一個執(zhí)行棧
主線程之外,事件觸發(fā)線程管理著一個任務(wù)隊列,只要異步任務(wù)有了運行結(jié)果,就在任務(wù)隊列之中放置一個事件。
一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢(此時JS引擎空閑),系統(tǒng)就會讀取任務(wù)隊列,將可運行的異步任務(wù)添加到可執(zhí)行棧中,開始執(zhí)行

事件循環(huán)是通過任務(wù)隊列的機制來進行協(xié)調(diào)的。一個 Event Loop 中,可以有一個或者多個任務(wù)隊列(task queue),一個任務(wù)隊列便是一系列有序任務(wù)(task)的集合;每個任務(wù)都有一個任務(wù)源(task source),源自同一個任務(wù)源的 task 必須放到同一個任務(wù)隊列,從不同源來的則被添加到不同隊列。 setTimeout/Promise 等API便是任務(wù)源,而進入任務(wù)隊列的是他們指定的具體執(zhí)行任務(wù)。

宏任務(wù):

macro)task(又稱之為宏任務(wù)),可以理解是每次執(zhí)行棧執(zhí)行的代碼就是一個宏任務(wù)(包括每次從事件隊列中獲取一個事件回調(diào)并放到執(zhí)行棧中執(zhí)行)。

瀏覽器為了能夠使得JS內(nèi)部(macro)task與DOM任務(wù)能夠有序的執(zhí)行,會在一個(macro)task執(zhí)行結(jié)束后,在下一個(macro)task 執(zhí)行開始前,對頁面進行重新渲染,流程如下:
(macro)task->渲染->(macro)task->...
(macro)task主要包含:script(整體代碼)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 環(huán)境)

微任務(wù):

microtask(又稱為微任務(wù)),可以理解是在當前 task 執(zhí)行結(jié)束后立即執(zhí)行的任務(wù)。也就是說,在當前task任務(wù)后,下一個task之前,在渲染之前。

所以它的響應速度相比setTimeout(setTimeout是task)會更快,因為無需等渲染。也就是說,在某一個macrotask執(zhí)行完后,就會將在它執(zhí)行期間產(chǎn)生的所有microtask都執(zhí)行完畢(在渲染前)。

microtask主要包含:Promise.then、MutaionObserver、process.nextTick(Node.js 環(huán)境)

運行機制:

在事件循環(huán)中,每進行一次循環(huán)操作稱為 tick,每一次 tick 的任務(wù)處理模型是比較復雜的,但關(guān)鍵步驟如下:

執(zhí)行一個宏任務(wù)(棧中沒有就從事件隊列中獲?。?執(zhí)行過程中如果遇到微任務(wù),就將它添加到微任務(wù)的任務(wù)隊列中
宏任務(wù)執(zhí)行完畢后,立即執(zhí)行當前微任務(wù)隊列中的所有微任務(wù)(依次執(zhí)行)
當前宏任務(wù)執(zhí)行完畢,開始檢查渲染,然后GUI線程接管渲染
渲染完畢后,JS線程繼續(xù)接管,開始下一個宏任務(wù)(從事件隊列中獲?。?/pre>

流程圖如下:

兩道題 讓你全部理解事件循環(huán)

console.log("1")
  setTimeout(function() {
    console.log("2")
    process.nextTick(function() {
      console.log("3")
    })
    new Promise(function(resolve) {
      console.log("4")
      resolve()
    }).then(function() {
      console.log("5")
    })
  })
  process.nextTick(function() {
    console.log("6")
  })
  new Promise(function(resolve) {
    console.log("7")
    resolve()
  }).then(function() {
    console.log("8")
  })
  setTimeout(function() {
    console.log("9")
    process.nextTick(function() {
      console.log("10")
    })
    new Promise(function(resolve) {
      console.log("11")
      resolve()
    }).then(function() {
      console.log("12")
    })
  })
  
  第二題
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");

注意:
async function async1() {                        
    console.log("async1 start");
    await async2();                   
    console.log("async1 end");
}
等同于
async function async1() {
    console.log("async1 start");
    Promise.resolve(async2()).then(() => {
            console.log("async1 end");
    })
}

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

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

相關(guān)文章

  • JavaScript事件循環(huán)(Event Loop)

    摘要:事件循環(huán)的順序,決定代碼執(zhí)行的順序。輸出第二輪事件循環(huán)正式結(jié)束三第三輪事件循環(huán)第三輪事件循環(huán)從宏任務(wù)開始。記為遇到,立即執(zhí)行回調(diào)函數(shù)放入中注冊,然后被分發(fā)到微任務(wù)事件隊列中。 1、為什么要有事件循環(huán)? 因為js是單線程的,事件循環(huán)是js的執(zhí)行機制,也是js實現(xiàn)異步的一種方法。 既然js是單線程,那就像只有一個窗口的銀行,客戶需要排隊一個一個辦理業(yè)務(wù),同理js任務(wù)也要一個一個順序執(zhí)行。如...

    dmlllll 評論0 收藏0
  • [譯]事件循環(huán),Node.js背后的核心概念

    摘要:事件處理器,則是當指定事件觸發(fā)時,執(zhí)行的一段代碼。事件循環(huán)以一個無限循環(huán)的形式啟動,存在于二進制文件里函數(shù)的最后,當沒有更多可被執(zhí)行的事件處理器時,它就退出。 前言 如果你了解過Node.js,那么你一定聽說過事件循環(huán)。你一定想知道它為什么那么特殊,并且為什么你需要關(guān)注它?此時此刻的你,可能已經(jīng)寫過許多基于Express.js的后端代碼,但沒有接觸到任何的循環(huán)。 在下文中,我們會先在一...

    Meils 評論0 收藏0
  • 淺談不同環(huán)境下的JavaScript執(zhí)行機制 + 示例詳解

    摘要:如果沒有其他異步任務(wù)要處理比如到期的定時器,會一直停留在這個階段,等待請求返回結(jié)果。執(zhí)行的執(zhí)行事件關(guān)閉請求的,例如事件循環(huán)的每一次循環(huán)都需要依次經(jīng)過上述的階段。因此,才會早于執(zhí)行。 showImg(https://segmentfault.com/img/bVbnY76); 概念 同步任務(wù)(Synchronous) 在主線程上排隊執(zhí)行的任務(wù),只有前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù) ...

    wanghui 評論0 收藏0
  • 由setTimeout和setImmediate執(zhí)行順序的隨機性窺探Node的事件循環(huán)機制

    摘要:問題引入接觸過事件循環(huán)的同學大都會糾結(jié)一個點,就是在中和執(zhí)行順序的隨機性。當隊列被執(zhí)行完,或者執(zhí)行的回調(diào)數(shù)量達到上限后,事件循環(huán)才會進入下一個階段。嵌套的在下一個事件循環(huán)的階段執(zhí)行回調(diào)輸出嵌套的。 問題引入 接觸過事件循環(huán)的同學大都會糾結(jié)一個點,就是在Node中setTimeout和setImmediate執(zhí)行順序的隨機性。 比如說下面這段代碼: setTimeout(() => { ...

    marek 評論0 收藏0
  • Node中的事件循環(huán)

    摘要:的事件循環(huán)一個線程有唯一的一個事件循環(huán)。索引就是指否還有需要執(zhí)行的事件,是否還有請求,關(guān)閉事件循環(huán)的請求等等。先來看一下定義的定義是在事件循環(huán)的下一個階段之前執(zhí)行對應的回調(diào)。雖然是這樣定義的,但是它并不是為了在事件循環(huán)的每個階段去執(zhí)行的。 Node中的事件循環(huán) 如果對前端瀏覽器的時間循環(huán)不太清楚,請看這篇文章。那么node中的事件循環(huán)是什么樣子呢?其實官方文檔有很清楚的解釋,本文先從n...

    lwx12525 評論0 收藏0
  • NodeJS架構(gòu) - 單線程事件循環(huán)模型

    摘要:客戶端可能需要等待服務(wù)器釋放可用的線程去處理其請求處理阻塞式的任務(wù)時浪費時間的架構(gòu)單線程事件循環(huán)不遵循請求響應多線程無狀態(tài)模型。它采用單線程與事件循環(huán)模型。 showImg(https://segmentfault.com/img/remote/1460000017402136); 這篇譯章探究了NodeJS的架構(gòu)和單線程事件循環(huán)模型。我們將在本文中討論NodeJS如何在底層工作,它遵...

    leap_frog 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<