<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Node 的 Events 模組只定義了一個類,就是 EventEmitter(以下簡稱 Event ),這個類在很多 Node 本身以及第三方模組中大量使用,通常是用作基礎類別被繼承。
在 Node 中,事件的應用遍及程式碼的每一個角落。
Node 程式中的物件會產生一系列的事件,它們被稱為事件觸發器(event emitter),例如一個 HTTP Server 會在每次有新連線時觸發一個事件,一個 Readable Stream 會在檔案開啟時觸發一個事件等。
所有能觸發事件的物件都是 EventEmitter
類的範例。EventEmitter
定義了 on
方法,該方法的宣告如下:
emitter.on(eventName, listener) eventName <String> | <Symbol> The name of the event. listener <Function> The callback function
on
方法接受兩個引數:需要監聽的事件的名稱,當事件觸發時需要呼叫的函數。因為 EventEmitter
是介面,從 EventEmitter
繼承的類需要使用 new
關鍵字來構造。
觸發事件監聽器很簡單,只要呼叫 EventEmitter
範例的 emit
方法就行了。需要注意的是,這些事件是針對某個範例的,不存在全域性的事件。當你呼叫 on
方法的時候,需要繫結在特定的基於 EventEmitter
的物件上。EventEmitter
類不同的範例之間也不會共用事件。
下面是一個事件註冊和觸發事件的例子。
const eventEmitter = require('events'); const myEmitter = new eventEmitter(); myEmitter.on('begin', () => { console.log('begin'); }); myEmitter.emit('begin');
上面的程式碼中,首先初始化了一個 EventEmitter
範例,然後註冊了一個名為 begin
的事件,之後呼叫 emit
方法觸發了這一事件。
使用者可以註冊多個同名的事件,在上面的例子中,如果註冊兩個名為 begin
的事件,那麼它們都會被觸發。
如果想獲取當前的 emitter
一共註冊了哪些事件,可以使用 eventNames
方法。
console.log(myEmitter.eventNames());
該方法會輸出包括全部事件名稱的陣列。就算註冊了兩個同名的 event
,輸出結果也只有一個,說明該方法的結果集並不包含重複結果。
由於 Node 程式碼執行在單執行緒環境中,那麼執行時出現的任何錯誤都有可能導致整個程序退出。利用事件機制可以實現簡單的錯誤處理功能。
當 Node 程式出現錯誤的時候,通常會觸發一個錯誤事件,如果程式碼中沒有註冊相應的處理方法,會導致 Node 程序崩潰退出。例如:
myEmitter.emit("error", new Error("crash!"));
上面的程式碼主動丟擲了一個 emor
,相當於:
throw new Error ("crash");
如果我們不想因為丟擲一個 error
而使程序退出,那麼可以讓 uncaughtException
事件作為最後一道防線來捕獲異常。
const eventEmitter = require('events'); const myEmitter = new eventEmitter(); process.on('uncaughtException', () => { console.log('got error'); }); throw new Error('Error occurred');
這種錯誤處理的方式雖然可以捕獲異常,避免了程序的退出,但不值得提倡。
關於其常見的方法如下:
emitter.addListener/on(eventName, listener)
:新增型別為 eventName
的監聽事件到事件陣列尾部emitter.prependListener(eventName, listener)
:新增型別為 eventName
的監聽事件到事件陣列頭部emitter.emit(eventName[, ...args])
:觸發型別為 eventName
的監聽事件emitter.removeListener/off(eventName, listener)
:移除型別為 eventName
的監聽事件emitter.once(eventName, listener)
:新增型別為 eventName
的監聽事件,以後只能執行一次並刪除emitter.removeAllListeners([eventName])
: 移除全部型別為 eventName
的監聽事件在實際的開發中,通常不會直接使用 Event 模組來進行事件處理,而是選擇將其作為基礎類別進行繼承的方式來使用 Event,在 Node 的內部實現中,凡是提供了事件機制的模組,都會在內部繼承 Event 模組。
下面我們來看看如何手寫一個 EventEmitter
。
class EventEmitter { constructor() { this.events = {}; } on(type, handler) { if (!this.events[type]) { this.events[type] = []; } this.events[type].push(handler); } addListener(type, handler) { this.on(type, handler) } prependListener(type, handler) { if (!this.events[type]) { this.events[type] = []; } this.events[type].unshift(handler); } removeListener(type, handler) { if (!this.events[type]) { return; } this.events[type] = this.events[type].filter(item => item !== handler); } off(type, handler) { this.removeListener(type, handler) } emit(type, ...args) { this.events[type].forEach((item) => { Reflect.apply(item, this, args); }); } once(type, handler) { this.on(type, this._onceWrap(type, handler, this)); } _onceWrap(type, handler, target) { const state = { fired: false, handler, type, target }; const wrapFn = this._onceWrapper.bind(state); state.wrapFn = wrapFn; return wrapFn; } _onceWrapper(...args) { if (!this.fired) { this.fired = true; Reflect.apply(this.handler, this.target, args); this.target.off(this.type, this.wrapFn); } } }
到此這篇關於Node中的Events事件介紹及應用的文章就介紹到這了,更多相關Node Events內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45