iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

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

Day20: EventEmitter

  • 分享至 

  • xImage
  •  

EventEmitter就是事件監聽器,在Nodejs中這事件無所不在,都是基於程序中的對象會產生事件,
會有觸發事件與監聽事件。透過傳送訊息表示操作已經完成來觸發事件。

比如: HTTP服務器

var http=require("http");
var server=http.createServer((req,res)=>
{
	 res.end("Hello Nicole");
});
server.on("connection",()=>{
    console.log("觸發connection");
});
server.on("request",()=>{
    console.log("觸發request");
})
server.listen(3000);

當HTTP請求時會觸發connection事件和request事件。

比如: Stream

var fs=require("fs");
var stream=require("stream");
var readStream=fs.createReadStream("./heartbeat.txt");
readStream.on("data",(nicole)=>
{
    console.log("有數據可以觸發!!"+"\n\n"+nicole+"\n");
});
readStream.on("end",()=>
{
    console.log("End!!!!沒有更多的數據可以觸發!!!");
});
readStream.on("err",()=>
{
    console.log("Error,過程發生錯誤");
});

Steam中的Readable會在文件開啟時觸發data事件,
當沒有更多的數據可讀時,觸發end事件。
執行結果:

https://ithelp.ithome.com.tw/upload/images/20211002/201402440iM0p4vR2q.png

回到EventEmitter本身:

  • 首先導入 events模塊:
var event=require("events");  //導入模塊
  • 建立對象:
var nicole=new event();  //設立對象
  • 建立監聽器註冊事件:
EventEmitter.on(event, listener) ;

在前些日子裡的例子有時候會看到on方法,比如說在DAY17: 實作提交表單的Post請求請求:

 req.on("data", (cb) => {
            arrary.push(cb);
        });

其實這個on方法就是被Events給定義的,代表插入了一個監聽器,
第一個參數為"監聽甚麼",第二個參數為callback函數,也就是當觸發了要做些甚麼。
像是上面這個例子要監聽的是data,一旦緩衝區的數據可以被讀取了,就調用函數,
把陣列裡的數據放到cb這個參數中。

  • 觸發事件
EventEmitter.emit(event, [arg1],[arg2]);
  • 註冊一個事件並觸發:
//註新註冊馨事件並觸發
var event=require("events");
var nicole=new event();
nicole.on("start",()=>{
    console.log("nicole start");
    console.log("Hello!!Nicole!!")
});
nicole.emit("start");
console.log(nicole.eventNames());

我註冊一個事件名為start,接著調用emit()觸發事件。
執行結果:
https://ithelp.ithome.com.tw/upload/images/20211002/20140244qmGrfNSz9A.png

而且可以透過eventName()來看註冊事件名稱(顯示["start"]的部分)。

處理error事件:

參考資料: 李鍇 著<新時期的Node.js入門>
在Nodejs中運行時出現的任何錯誤都可能讓整個進程退出或是崩潰,
我在實作的過程中也常常有發生錯誤的時候,可能有些是自己的失誤,
或是某些事件未被定義,會出現以下類似的畫面:

https://ithelp.ithome.com.tw/upload/images/20211002/20140244az2VlqWOpe.png

整個Nodejs會輸出整個錯誤線,像是上面這個錯誤就是沒有找到event這個模塊(因為我打錯字了…)。
但如果不想因為每次拋出一個error就使進程退出,可以使uncaughtException事件捕獲異常作為最後一道防線。

//uncaughtException捕獲異常
var event=require("events");
var nicole=new event();
process.on("uncaughtException",()=>
{
    console.log("ERROR!!!!!!!!!!!!!!!!!!!!");
});
throw new Error("Errpr occurred");

但經過查資料也發現,雖然這個處理方式很萬用,
但若是在Web中出現錯誤,使用uncaughtException事件就會遺失錯誤發生的上下文,並不利於定位錯誤碼。


上一篇
DAY19: Stream pipe()做起來!!
下一篇
DAY21: NPM模塊管理工具
系列文
Node.js 非專業解說30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言