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
事件。
執行結果:
回到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()
觸發事件。
執行結果:
而且可以透過eventName()
來看註冊事件名稱(顯示["start"]
的部分)。
參考資料: 李鍇 著<新時期的Node.js入門>
在Nodejs中運行時出現的任何錯誤都可能讓整個進程退出或是崩潰,
我在實作的過程中也常常有發生錯誤的時候,可能有些是自己的失誤,
或是某些事件未被定義,會出現以下類似的畫面:
整個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事件就會遺失錯誤發生的上下文,並不利於定位錯誤碼。