node.js學(xué)習(xí)之事件模塊Events的使用示例
前言
本文主要給大家介紹了關(guān)于node.js事件模塊Events使用的一些示例,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。
環(huán)境:Node v8.2.1; Npm v5.3.0; OS Windows10
1、 Node事件介紹
Node大多數(shù)核心 API 都采用慣用的異步事件驅(qū)動架構(gòu),其中某些類型的對象(觸發(fā)器)會周期性地觸發(fā)命名事件來調(diào)用函數(shù)對象(監(jiān)聽器)。
所有能觸發(fā)事件的對象都是 EventEmitter 類的實(shí)例。 這些對象開放了一個 eventEmitter.on() 函數(shù),允許將一個或多個函數(shù)綁定到會被對象觸發(fā)的命名事件上。 事件名稱通常是駝峰式的字符串,但也可以使用任何有效的 JavaScript 屬性名。
當(dāng) EventEmitter 對象觸發(fā)一個事件時,所有綁定在該事件上的函數(shù)都被同步地調(diào)用。 監(jiān)聽器的返回值會被丟棄。
2、events 模塊API介紹

3、 一些例子
下面是一些簡單的例子,對應(yīng)上面的API的一個代碼實(shí)現(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 實(shí)例:
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 實(shí)例中發(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"))
上面這樣的方式并不是最佳實(shí)踐,最好是為【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 實(shí)例的監(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 實(shí)例會在一個監(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
*/
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
node.js中的fs.realpathSync方法使用說明
這篇文章主要介紹了node.js中的fs.realpathSync方法使用說明,本文介紹了fs.realpathSync的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
win7下安裝配置node.js+express開發(fā)環(huán)境
windows7下安裝nodejs及框架express,從誕生至今一直被熱捧,筆者最近也裝了個環(huán)境打算了解一下。安裝步驟簡單比較簡單,這里分享給大家,希望大家能夠喜歡。2015-12-12
Node.js的Koa實(shí)現(xiàn)JWT用戶認(rèn)證方法
本篇文章主要介紹了Node.js的Koa實(shí)現(xiàn)JWT用戶認(rèn)證方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
詳解nodejs的express如何自動生成項(xiàng)目框架
本篇文章主要介紹了nodejs的express如何自動生成項(xiàng)目框架,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
在nodejs中創(chuàng)建child process的方法
這篇文章主要介紹了在nodejs中創(chuàng)建child process的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01
詳解nodejs微信公眾號開發(fā)——1.接入微信公眾號
本篇文章主要介紹了詳解nodejs微信公眾號開發(fā)——1.接入微信公眾號,非常具有實(shí)用價值,需要的朋友可以參考下2017-04-04
node.js中的http.response.end方法使用說明
這篇文章主要介紹了node.js中的http.response.end方法使用說明,本文介紹了http.response.end的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
Node.js利用debug模塊打印出調(diào)試日志的方法
debug日志打印模塊主要實(shí)現(xiàn)功能是帶命名空間(模塊名)、時間戳、色彩輸出日志;將日志寫入文件;瀏覽器端使用;格式化函數(shù);支持自定義方法。下面這篇文章主要介紹了Node.js利用debug模塊打印出調(diào)試日志的方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-04-04

