iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Modern Web

Node.js 非專業解說系列 第 11

DAY11: Node基礎總整理

  • 分享至 

  • xImage
  •  

前幾篇的互相比較來比較去的,是不是都有點亂了思緒,今天來做個小複習,從DAY5: node 的內部機制(一)DAY10: setTimeout和setImmediate的比較做個簡單總整理。

同步:

  • 進程和線程的調用方式。
  • 會一直等待調用返回後才會繼續執行後續。
  • 簡單的說,會依照輸入的指令順序做處理。

非同步:

  • 進程和線程的調用方式。
  • 與同步相反,當發起調用後,會繼續執行下一個動作,當調用返回後,才會透過回調函數開啟。

阻塞:

  • 針對I/O的調用方式。
  • I/O在進程發出調用請求後,就一直等待直到數據準備完成與結果,都取得後再繼續執行。
  • 不會去一直檢視內核狀態

非阻塞:

  • 針對I/O的調用方式。
  • 與阻塞相反,若數據準備與結果都還沒取得,會返回上一個結果讓進程知道還未準備就緒。
  • 會不斷地檢視內核的狀態。

Node事件循環:

總共有六個不同階段,每個階段都有自己的回調函數,處理著不同的事件,依序是:
1. timers:

  • 用來執行處理setTimeOut()setInterval()的回調。
  • 若在處理一個耗時的回調,定時的回調就只能等待回調結束才能被執行,等於被阻塞了。
  • timers階段的執行會被poll階段所控制。

2. I/O callbacks:

  • 執行處理系統錯誤的回調。

3. poll:

  • 不斷來回檢視是否有新的I/O事件發生
  • 若沒有新的事件發生,這裡可能產生阻塞的階段。
  • 對於設置了定時(位於timers階段或check階段設置的setImmediate()):當定時時間到,就執行定時的回調方法與
    poll事件隊列中對應的事件。
    若poll階段為空了:
    若有設置setImmediate(),事件循環會跳出poll階段,進入check階段執行setImmediate()的回調方法。
    若沒有設置setImmediate(),事件循環進入等待新事件產生。

4. idle,prepare:

  • 僅於node內部使用,不須理會。

5. Check:

  • 主幹就是setImmediate()
  • 為了處理setImmediate() 的回調,而佔據事件循環的一個階段。

6. Close callbacks:

  • close在此發出事件。
  • 這輪事件循環結束。

Process.nextTick():

  • 並非事件循環的一部份。
  • 是一個異步的動作,此動作在事件循環當前階段結書後才會執行。
  • 佇列nextTickQueue被限制了大小,在遞迴中會產生錯誤。
  • 若出現死循環,會產生阻塞。

setImmediate():

  • 在poll階段觸發,對應回調方法在check階段執行。
  • 不會產生呼叫堆疊,故遞迴可以在此使用

setTimeout():

  • 由於無法得知在執行的情況下事件循環到哪一個階段了,故與setImmediate()一同出現的話,
    它們發生的順序每一次 都不一定相同
  • 若是放在I/O的回調中,則一直會是setImmediate()先被執行。

三者優先順序:
process.nextTick > setTimeout > setImmediate

實際例子:

//大亂鬥
process.nextTick(()=>
{
  console.log("nextTick!! I'm NO.1 ");
},);

require('fs').readFile("butterfly.txt",function(Nicole)
{
    setImmediate(function(Nicole)
{
    console.log("immediate !! I'm NO.2");
});
setTimeout(function(Nicole)
{
    console.log("Timeout I'm NO.3");
},0);
});

執行結果:

https://ithelp.ithome.com.tw/upload/images/20210922/20140244AeBuab3ssI.jpg


上一篇
DAY10: setTimeout和setImmediate的比較
下一篇
DAY12 : HTTP前情提要
系列文
Node.js 非專業解說30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言