您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)如何在node.js中使用Events模塊,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
1、 Node事件介紹
Node大多數(shù)核心 API 都采用慣用的異步事件驅(qū)動架構(gòu),其中某些類型的對象(觸發(fā)器)會周期性地觸發(fā)命名事件來調(diào)用函數(shù)對象(監(jiān)聽器)。
所有能觸發(fā)事件的對象都是 EventEmitter 類的實例。 這些對象開放了一個 eventEmitter.on() 函數(shù),允許將一個或多個函數(shù)綁定到會被對象觸發(fā)的命名事件上。 事件名稱通常是駝峰式的字符串,但也可以使用任何有效的 JavaScript 屬性名。
當(dāng) EventEmitter 對象觸發(fā)一個事件時,所有綁定在該事件上的函數(shù)都被同步地調(diào)用。 監(jiān)聽器的返回值會被丟棄。
2、events 模塊API介紹
3、 一些例子
下面是一些簡單的例子,對應(yīng)上面的API的一個代碼實現(xiàn)
3.1 綁定和觸發(fā)事件
const EventEmitter = require('events'); //自定義一個對象繼承于EventEmitter class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); myEmitter.on('event', () => { console.log('觸發(fā)了一個事件!'); }); myEmitter.emit('event');
3.2 為事件傳遞參數(shù)
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', (a,b) => { console.log(a,b); //1,2 }); myEmitter.emit('event','a','b');
3.3 this 的問題
當(dāng)一個普通的監(jiān)聽器函數(shù)被 EventEmitter 調(diào)用時,標(biāo)準(zhǔn)的 this 關(guān)鍵詞會被設(shè)置指向監(jiān)聽器所附加的 EventEmitter。
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', function() { console.log(this); /* a b MyEmitter { domain: null, _events: { event: [Function] }, _eventsCount: 1, _maxListeners: undefined } */ }); myEmitter.emit('event');
也可以使用 ES6 的箭頭函數(shù)作為監(jiān)聽器。但是這樣 this 關(guān)鍵詞就不再指向 EventEmitter 實例:
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', () => { console.log(this); //{} }); myEmitter.emit('event');
3.4 異步執(zhí)行
EventListener 會按照監(jiān)聽器注冊的順序同步地調(diào)用所有監(jiān)聽器,監(jiān)聽器函數(shù)可以使用 setImmediate()
或 process.nextTick()
方法切換到異步操作模式:
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', (a,b) => { setImmediate(()=>{ //異步觸發(fā) console.log(a,b); }) console.log("c"); }); myEmitter.emit('event','a','b'); //c //a b
3.5 無限次觸發(fā)和一次觸發(fā)
事件默認(rèn)是可以無限次數(shù)的觸發(fā)的,只要觸發(fā)一次,對應(yīng)的監(jiān)聽函數(shù)就執(zhí)行一次;有時候我們希望只執(zhí)行一次監(jiān)聽函數(shù),可以使用【once】對事件進(jìn)行綁定
多次觸發(fā):
const EventEmitter = require('events') class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); let m = 0; myEmitter.on('event', () => { console.log(++m); }); myEmitter.emit('event'); //1 myEmitter.emit('event'); //2 myEmitter.emit('event'); //3
一次觸發(fā):
const EventEmitter = require('events') class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); let m = 0; myEmitter.once('event', () => { console.log(++m); }); myEmitter.emit('event'); //1 myEmitter.emit('event'); //忽略 myEmitter.emit('event'); //忽略
3.6 錯誤事件
當(dāng) EventEmitter 實例中發(fā)生錯誤時,會觸發(fā)一個 ‘error' 事件,如果 EventEmitter 沒有為 ‘error' 事件注冊至少一個監(jiān)聽器,則當(dāng) ‘error' 事件觸發(fā)時,會拋出錯誤、打印堆棧跟蹤、且退出 Node.js 進(jìn)程。
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); myEmitter.emit("error", new Error('whoops!')); // 拋出錯誤,并使 Node.js 崩潰
為了防止 Node.js 進(jìn)程崩潰,可以在 process 對象的 uncaughtException 事件上注冊監(jiān)聽器
const EventEmitter = require('events') class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); //在進(jìn)程上面注冊錯誤監(jiān)聽,使進(jìn)程不崩潰 process.on("uncaughtException",()=>{ console.error('有錯誤'); }); myEmitter.emit("error",new Error("whoops"))
上面這樣的方式并不是最佳實踐,最好是為【error】注冊監(jiān)聽函數(shù)
3.7 獲取和修改最大事件監(jiān)聽數(shù)量
Node默認(rèn)一個事件的監(jiān)聽數(shù)量為10個,超過十個將會發(fā)出警告
const EventEmitter = require('events') class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); console.log(EventEmitter.defaultMaxListeners); //10 for (let i = 0; i < 11; i++) { myEmitter.on("event", () => { console.log(i); }); } myEmitter.emit("event") //MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 event listeners added. Use emitter.setMaxListeners() to increase limit
改變指定的 EventEmitter 實例的監(jiān)聽器限制
const EventEmitter = require('events') class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); myEmitter.setMaxListeners(13); for (let i = 0; i < 11; i++) { myEmitter.on("event", () => { console.log(i); }); } myEmitter.emit("event")
3.8 newListener事件
EventEmitter 實例會在一個監(jiān)聽器被添加到其內(nèi)部監(jiān)聽器數(shù)組【之前】觸發(fā)自身的 ‘newListener' 事件
const EventEmitter = require('events') class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter() myEmitter.once("newListener", (event, listener) => { if(event === "event"){ myEmitter.on("event",()=>{ console.log("B"); }) } }); myEmitter.on("event",()=>{ console.log("A"); }); myEmitter.emit("event") /* B A */
看完上述內(nèi)容,你們對如何在node.js中使用Events模塊有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。