Node.js初學筆記5-了解EventsEmitter物件(on(),emit())

今天要介紹Node.js中相當重要的概念-事件監控與觸發,我們之前在JS中已經接觸過事件監控的概念,沒錯!就是addEventListener!

const inputBox = document.querySelector('#inputBox')
inputBox.addEventListener('input',function(e){
  console.log(e)
}

使用時其實已經相當方便,但由於事件的類型是內建的(click、input等),超出這些預設範圍的事件便沒有辦法執行對應操作,因此node.js中便有了on & emit的概念出現!
遇到陌生名詞別擔心,其實很好懂的,只要你不去探究背後的邏輯(笑)

On & Emit

首先我們要載入Node本身的module-events並建立一個實例

 const EE = require('events').EventEmitter 
 let greeter = new EE() 

物件greeter就可以使用EventEmitter內的method囉!

首先我們要利用on先加入事件的類型並進行監聽,基本語法如下

greeter.on(type,function)
//type為自定義的事件,function則為對應的處理方式

今天我們先設置個簡單的打招呼事件!

greeter.on('greet',function(){
  console.log('Hi I am Danny')
}) 

設置完事件後接著便利用emit執行這個事件,基本語法如下

emit(type[,..args])
//type為你設置過的事件,arg則是要傳入的變數)

我們利用emit來執行"greet’事件,我想你很清楚結果會是什麼樣子了

emit('greet')  //  Hi I am Danny 

看起來相當簡單對吧?那我們看一下以下的程式碼

const EE = require('events').EventEmitter 
let greeter = new EE()

greeter.on('greet',function(){
  console.log('Hi I am Danny')
})

greeter.on('greet',function(){
  console.log("How you doin'?")
})
 

emit('greet')    

你可能會想,第二個on指向的事件也是greet,所以會覆寫掉之前的callback,最終輸出結果應該只有How you doin’,可惜不是的,它會乖乖的兩句都印出來。讓我解釋一下原因。

On & Emit Under the hood

首先,在你利用on設立任何物件前,greeter內的事件其實會是個空物件,我們先叫它events(可以去查一下node.js內本身的events文件,對於結構會更了解)

//greeter內部
events = {
  //這時候什麼都沒有
}

當你利用on建立事件時,它會變成像是這樣,假設我們今天設立了兩個事件,events本身會變成

greeter.on('greet',function() {
  console.log('Hi I am Danny')
}

greeter.on('greet',function() {
  console.log('How are you')
} 

greeter.on('kick', function() {
  console.log('I kick someone else')
}

//greeter內部
events = {
  'greet':[function(), function()], //第一個函式會印出Hi I am Danny 第二則是How are you
  'kick': [function()]

} 

也就是說,當你利用on設立事件時,Node首先會先查看是否有相同的事件存在,若沒有則建立一個key-value pair,若有 則把對應的函式加入陣列中。

最後, 當你輸入emit(‘greet’)的時候 ,node 去事件物件中找對應的key值(也就是事件名稱),接著按順序執行陣列內所有的函式,這才造就了我們今天練習的結果,很有意思吧?

結語

EventsEmitter是個極端重要的概念,我們雖然不會直接在node中使用它,但會透過繼承的方式來使用裡面的一些method,搞懂它的基礎概念會是很重要的一步,我很慶幸自己多花了許多時間了解背後的概念!

發表留言