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

資訊專欄INFORMATION COLUMN

理解瀏覽器和node.js中的Event loop事件循環(huán)

iliyaku / 2002人閱讀

摘要:瀏覽器和中并不一樣,瀏覽器的是在中定義的規(guī)范,而中則由庫實(shí)現(xiàn)。整個(gè)的這種運(yùn)行機(jī)制又稱為事件循環(huán)例子了解瀏覽器的后,查看下面例子,猜測瀏覽器是怎么輸出的瀏覽器輸出中的在內(nèi)部有這樣一個(gè)事件環(huán)機(jī)制。在啟動時(shí)會初始化事件環(huán)。執(zhí)行和中到期的。

大家都知道,javascript是一門單線程語言,因此為了實(shí)現(xiàn)主線程的不阻塞,Event Loop這樣的方案應(yīng)運(yùn)而生。

瀏覽器和node中Event loop并不一樣,瀏覽器的Event loop是在HTML5中定義的規(guī)范,而node中則由libuv庫實(shí)現(xiàn)。

瀏覽器中的Event loop

所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧

主線程之外,還存在一個(gè)任務(wù)隊(duì)列。

任務(wù)隊(duì)列分為macro-task(宏任務(wù))和micro-task(微任務(wù))。

macro-task(宏任務(wù)): setTimeout, setInterval, setImmediate, I/O等

micro-task(微任務(wù)): process.nextTick, 原生Promise(有些實(shí)現(xiàn)的promise將then方法放到了宏任務(wù)中),Object.observe(已廢棄), MutationObserver等

整個(gè)最基本的Event Loop如圖所示:

具體過程:

瀏覽器中,先執(zhí)行當(dāng)前棧,執(zhí)行完主執(zhí)行線程中的任務(wù)。

取出Microtask微任務(wù)隊(duì)列中任務(wù)執(zhí)行直到清空。

取出Macrotask宏任務(wù)中 一個(gè) 任務(wù)執(zhí)行。

檢查Microtask微任務(wù)中有沒有任務(wù),如果有任務(wù)執(zhí)行直到清空。

重復(fù)3和4。

整個(gè)的這種運(yùn)行機(jī)制又稱為Event Loop(事件循環(huán))

例子

了解瀏覽器的Event loop后,查看下面例子,猜測瀏覽器是怎么輸出的

console.log(1);
console.log(2);
setTimeout(function(){
  console.log("setTimeout1");
  Promise.resolve().then(function(){
    console.log("Promise")
  })
})
setTimeout(function(){
  console.log("setTimeout2");
})

//瀏覽器輸出:1 2 setTimeout1 Promise setTimeout2

node中的Event loop

在libuv內(nèi)部有這樣一個(gè)事件環(huán)機(jī)制。在node啟動時(shí)會初始化事件環(huán)。

node中的event loop分為6個(gè)階段,不同于瀏覽器的是,這里每一個(gè)階段都對應(yīng)一個(gè)事件隊(duì)列,node會在當(dāng)前階段中的全部任務(wù)執(zhí)行完,清空NextTick Queue,清空Microtask Queue,再執(zhí)行下一階段。

在node.js里,process 對象代表node.js應(yīng)用程序,可以獲取應(yīng)用程序的用戶,運(yùn)行環(huán)境等各種信息。process.nextTick()方法將 callback 添加到next tick 隊(duì)列,并且nextTick優(yōu)先級比promise等microtask高。

timers:執(zhí)行setTimeout() 和 setInterval()中到期的callback。

I/O callbacks:上一輪循環(huán)中有少數(shù)的I/Ocallback會被延遲到這一輪的這一階段執(zhí)行

idle, prepare:隊(duì)列的移動,僅內(nèi)部使用

poll:最為重要的階段,執(zhí)行I/O callback,在適當(dāng)?shù)臈l件下會阻塞在這個(gè)階段

check:執(zhí)行setImmediate的callback

close callbacks:執(zhí)行close事件的callback,例如socket.on("close",func)

例子

查看下面例子加深對event loop的理解

在node執(zhí)行下面代碼,發(fā)現(xiàn)每次執(zhí)行先后順序不一樣,因?yàn)閚ode需要啟動時(shí)間,執(zhí)行過程中setTimeout可能到時(shí)間了也可能沒到時(shí)間,所以這個(gè)先后順序取決于node的執(zhí)行時(shí)間。

setTimeout(function(){
  console.log("timeout")  
})
setImmediate(function(){
  console.log("immediate")
})

i/o操作階段完成后,會走check階段,所以setImmediate會優(yōu)先走

let fs=require("fs");
fs.readFile("./1.log",function(){
  console.log("fs");
  setTimeout(function(){
    console.log("timeout")
  })
  setImmediate(funciton(){
     console.log("setTimmediate")          
  })
})

nextTick應(yīng)用場景

function Fn(){
  this.arrs;
  process.nextTick(()=>{ //根據(jù)nextTick的特性,可以先賦值,再在下一個(gè)隊(duì)列中使用
    this.arrs();
  })
}
Fn.prototype.then=function(){
  this.arrs=function(){console.log(1)}
}
let fn=new Fn();
fn.then();

//注意:nextTick千萬不要寫遞歸,不然會造成死循環(huán)。可以放一些比setTimeout優(yōu)先執(zhí)行的任務(wù)

總結(jié)

同一個(gè)上下文下,MicroTask微任務(wù)會比MacroTask宏任務(wù)先運(yùn)行。

瀏覽器是先取出一個(gè)MacroTask宏任務(wù)執(zhí)行,再執(zhí)行MicroTask微任務(wù)中的所有任務(wù)。Node是按照六個(gè)階段執(zhí)行,每個(gè)階段切換時(shí),再執(zhí)行MicroTask微任務(wù)隊(duì)列

同個(gè)MicroTask隊(duì)列下process.tick()會優(yōu)于Promise

setImmdieate()和setTimeout(),如果他們在異步i/o callback之外調(diào)用(在i/o內(nèi)調(diào)用因?yàn)橄乱浑A段為check階段),其執(zhí)行先后順序是不確定的,需要看loop的執(zhí)行前的耗時(shí)情況。

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

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

相關(guān)文章

  • 初窺JavaScript事件機(jī)制的實(shí)現(xiàn)(一)—— Node.js事件驅(qū)動實(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ū)動模型則是其高并發(fā)能力的基礎(chǔ)。 學(xué)習(xí)JavaScript也需要了解它的運(yùn)行平臺,為了更好的理解JavaScript的事...

    lavor 評論0 收藏0
  • FE.ES-理解Event Loop

    摘要:新加了一個(gè)微任務(wù)和一個(gè)宏任務(wù)在當(dāng)前執(zhí)行棧的尾部下一次之前觸發(fā)回調(diào)函數(shù)。階段這個(gè)階段主要執(zhí)行一些系統(tǒng)操作帶來的回調(diào)函數(shù),如錯(cuò)誤,如果嘗試鏈接時(shí)出現(xiàn)錯(cuò)誤,一些會把這個(gè)錯(cuò)誤報(bào)告給。 JavaScript引擎又稱為JavaScript解釋器,是JavaScript解釋為機(jī)器碼的工具,分別運(yùn)行在瀏覽器和Node中。而根據(jù)上下文的不同,Event loop也有不同的實(shí)現(xiàn):其中Node使用了libu...

    longshengwang 評論0 收藏0
  • 一篇文章教會你Event loop——覽器Node

    摘要:如果沒到毫秒,那么階段就會跳過,進(jìn)入階段,先執(zhí)行的回調(diào)函數(shù)。參考文檔什么是瀏覽器的事件循環(huán)不要混淆和瀏覽器中的定時(shí)器詳解瀏覽器和不同的事件循環(huán)深入理解事件循環(huán)機(jī)制篇中的執(zhí)行機(jī)制 最近對Event loop比較感興趣,所以了解了一下。但是發(fā)現(xiàn)整個(gè)Event loop盡管有很多篇文章,但是沒有一篇可以看完就對它所有內(nèi)容都了解的文章。大部分的文章都只闡述了瀏覽器或者Node二者之一,沒有對比...

    Leck1e 評論0 收藏0
  • 覽器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)同意請勿轉(zhuǎn)載。 前言 本文我們將會介紹 JS 實(shí)現(xiàn)異步的原理,并且了解了在瀏覽器和 Node 中 Event Loop 其實(shí)是不相同的。 一、線程與進(jìn)程 1. 概念 我們經(jīng)常說 JS 是單線程執(zhí)行的,...

    TANKING 評論0 收藏0
  • 理解JS中的Event Loop機(jī)制

    摘要:前言前幾天在理解的事件環(huán)機(jī)制中引發(fā)了我對瀏覽器里的好奇。接下來理解瀏覽器中的,先看一張圖堆和棧堆是用戶主動請求而劃分出來的內(nèi)存區(qū)域,比如你,就是將一個(gè)對象存入堆中,可以理解為存對象。廢話不多說,直接上圖個(gè)人理解。參考資料運(yùn)行機(jī)制詳解再談 前言 前幾天在理解node的事件環(huán)機(jī)制中引發(fā)了我對瀏覽器里Event Loop的好奇。我們都知道javascript是單線程的,任務(wù)是需要一個(gè)一個(gè)按順...

    MASAILA 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<