環(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 類的實例。 這些對象開放了一個 eventEmitter.on() 函數(shù),允許將一個或多個函數(shù)綁定到會被對象觸發(fā)的命名事件上。 事件名稱通常是駝峰式的字符串,但也可以使用任何有效的 JavaScript 屬性名。
當 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 的問題
當一個普通的監(jiān)聽器函數(shù)被 EventEmitter 調(diào)用時,標準的 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 b3.5 無限次觸發(fā)和一次觸發(fā)
事件默認是可以無限次數(shù)的觸發(fā)的,只要觸發(fā)一次,對應(yīng)的監(jiān)聽函數(shù)就執(zhí)行一次;有時候我們希望只執(zhí)行一次監(jiān)聽函數(shù),可以使用【once】對事件進行綁定
多次觸發(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 錯誤事件
當 EventEmitter 實例中發(fā)生錯誤時,會觸發(fā)一個 "error" 事件,如果 EventEmitter 沒有為 "error" 事件注冊至少一個監(jiān)聽器,則當 "error" 事件觸發(fā)時,會拋出錯誤、打印堆棧跟蹤、且退出 Node.js 進程。
const EventEmitter = require("events"); class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); myEmitter.emit("error", new Error("whoops!")); // 拋出錯誤,并使 Node.js 崩潰
為了防止 Node.js 進程崩潰,可以在 process 對象的 uncaughtException 事件上注冊監(jiān)聽器
const EventEmitter = require("events") class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); //在進程上面注冊錯誤監(jiān)聽,使進程不崩潰 process.on("uncaughtException",()=>{ console.error("有錯誤"); }); myEmitter.emit("error",new Error("whoops"))
上面這樣的方式并不是最佳實踐,最好是為【error】注冊監(jiān)聽函數(shù)
3.7 獲取和修改最大事件監(jiān)聽數(shù)量Node默認一個事件的監(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 */
CSDN 【Node事件模塊Events】同步更新
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/88738.html
摘要:實現(xiàn)方式其實就是對方法做了一層封裝,將一個封裝好的代替?zhèn)鬟f給方法內(nèi)部會執(zhí)行一次監(jiān)聽回調(diào)函數(shù),然后再調(diào)用對該回調(diào)進行刪除。 事件驅(qū)動 Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境。Node.js 使用了一個事件驅(qū)動、非阻塞式 I/O的模型,使其輕量又高效。Allows you to build scalable network applicati...
摘要:為什么把叫做集合而不能稱為嚴格意義上的對象,來看這個集合的構(gòu)造函數(shù)可以見得,是與處于同一層級的而非是繼承自,所以說由實例出來的對象更加的純凈,并沒有諸如等方法,更像是一個集合。 寫在前面 事件的編程方式具有輕量級、松耦合、只關(guān)注事務(wù)點等優(yōu)勢,在瀏覽器端,有著自己的一套DOM事件機制,其中含包括這諸如事件冒泡,事件捕獲等;然而Node的事件機制沒有事件冒泡等,其原理就是設(shè)計模式中的觀察者...
摘要:如果不能快速返回,就應(yīng)當將其遷移到另一個進程中模塊讓開發(fā)人員可以為事件設(shè)置偵聽器和處理器。我們需要給每個想要響應(yīng)的事件創(chuàng)建偵聽器 Node.js的http服務(wù)器 通過使用HTTP模塊的低級API,Node.js允許我們創(chuàng)建服務(wù)器和客戶端。剛開始學node的時候,我們都會遇到如下代碼: var http = require(http); http.createServer(funct...
摘要:事件的監(jiān)聽與事件的觸發(fā)事件一事件機制的實現(xiàn)中大部分的模塊,都繼承自模塊。從另一個角度來看,事件偵聽器模式也是一種事件鉤子的機制,利用事件鉤子導出內(nèi)部數(shù)據(jù)或狀態(tài)給外部調(diào)用者。的核心就是事件發(fā)射與事件監(jiān)聽器功能的封裝。 nodejs事件的監(jiān)聽與事件的觸發(fā) nodejs事件(Events)showImg(https://segmentfault.com/img/bV0Sqi?w=692&h=...
摘要:實例方法的話,最核心的就是分別是添加事件,刪除事件,發(fā)布事件。為了防止進程崩潰,可以在對象的事件上注冊監(jiān)聽器,或使用模塊。注意,模塊已被廢棄。作為最佳實踐,應(yīng)該始終為事件注冊監(jiān)聽器。 前言 事件在js中非常的常見,不管是瀏覽器還是node,這種事件發(fā)布/訂閱模式的應(yīng)用都是很常見的。至于發(fā)布/訂閱模式和觀察者模式是否是同一種設(shè)計模式說法都有,這里不做具體的討論。在之前的項目中也曾自己實現(xiàn)...
閱讀 2387·2023-04-26 01:50
閱讀 831·2021-09-22 15:20
閱讀 2697·2019-08-30 15:53
閱讀 1749·2019-08-30 12:49
閱讀 1811·2019-08-26 14:05
閱讀 2801·2019-08-26 11:42
閱讀 2415·2019-08-26 10:40
閱讀 2682·2019-08-26 10:38