站長資訊網
        最全最豐富的資訊網站

        Node.js學習之聊聊Events模塊

        本篇文章帶大家了解一下Node.js中的Events模塊,介紹一下 Events 中的發布訂閱模式,希望對大家有所幫助!

        Node.js學習之聊聊Events模塊

        Events模塊

        參考官網:events 事件觸發器 | Node.js

        http://nodejs.cn/api/events.html

        Events 模塊是Node最重要的模塊,它提供了一個屬性 EventEmitterEventEmitter 的核心是事件發射與事件監聽器。

        Node中大部分的模塊,都繼承自 Events 模塊。

        • Events 模塊是Node對 發布訂閱模式publish/subscribe)的實現。一個對象通過這個模塊,向另一個對象傳遞消息。
        • 該模塊通過 EventEmitter 屬性,提供了一個構造函數。該構造函數的實例具有 on 方法,可以用來監聽指定事件,并觸發回調函數。
        • 任意對象都可以發布指定事件,被 EventEmitter 實例的on方法監聽到。

        發布訂閱模式

        關于 發布訂閱模式 ,可以參考我之前的博客文章。

        關于 Events 中的發布訂閱模式,我們要先清楚它的幾個常用方法。

        • 訂閱方法on 方法用來訂閱事件,訂閱是將方法對應成一種一對多的關系。
        • 發布方法emit 用來執行訂閱的事件。
        • 取消訂閱off 方法可以移除對應的事件監聽。
        • 訂閱一次once 綁定事件當執行后自動刪除訂閱的事件。

        on 和 emit

        on 方法的第一個參數用來設定類名,第二個參數也是一個函數,里面可以接收發布時傳入的參數。

        emit 方法第一個參數是類名,之后的參數都是傳入 on 方法函數中的參數。

        onemit 具體應用可以參考下面這個簡單的Demo。

        const EventEmitter = require('events'); // 自定義一個 構造函數 function Cat() {} // 原型繼承 需要通過實例來調用繼承方法 Object.setPrototypeOf(Cat.prototype, EventEmitter.prototype); let cat = new Cat(); const sleep = (a, b) => {     console.log(a, '睡'); }; const eat = (a, b) => {     console.log(b, '吃'); }; cat.on('貓咪', sleep) cat.on('貓咪', eat) setTimeout(() => {   	// 小胡子 吃   	// 小胖仙 睡     cat.emit('貓咪', '小胖仙', '小胡子') }, 1000);

        現在我們可以實現一套 onemit 方法。

        function EventEmitter() {     this._event = {} } // on 方法 EventEmitter.prototype.on = function (eventName, callBack) {     if (!this._event) {         this._event = {}     }     if (this._event[eventName]) {         this._event[eventName].push(callBack) // 相當于 {eventName:[fn1,fn2]}     } else {         this._event[eventName] = [callBack]; // 相當于 {eventName:[fn1]}     }  } // emit 方法 EventEmitter.prototype.emit = function (eventName, ...args) {     this._event[eventName].forEach(fn => {         fn(...args)     }); }

        off

        off 方法的第一個參數用來設定類名,第二個參數傳入需要被移除的函數回調。

        // ... setTimeout(() => {   	// 小胡子 吃   	// 小胖仙 睡     cat.emit('貓咪', '小胖仙', '小胡子')   	cat.off('貓咪', sleep);   	// 小胡子 吃     cat.emit('貓咪', '小胖仙', '小胡子') }, 1000);

        這樣我們可以大概判斷出來,移除掉和我們傳入函數相同的函數,我們很快想到 filter 方法。

        // off 方法 EventEmitter.prototype.off = function (eventName, callBack) {     if (this._event && this._event[eventName]) {         this._event[eventName] = this._event[eventName].filter(           fn => fn !== callBack && fn.c !== callBack // fn.c參考下面的once方法實現         )     } }

        once

        once 方法的第一個參數用來設定類名,第二個參數傳入只需要執行一次的函數回調。

        // ... const demolition =() => {     console.log('拆家'); } cat.once('貓咪', demolition) setTimeout(() => {   	// ...... 拆家     cat.emit('貓咪', '小胖仙', '小胡子') }, 1000);

        這樣我們可以根據之前實現的 onoff 來實現此方法。

        // once 方法 EventEmitter.prototype.once = function (eventName, callBack) {     const one = () => {         callBack();         this.off(eventName, one);     }     this.on(eventName, one); }

        看起來這個方法好像沒有什么問題,執行起來也全都是正確的。

        但是在一種特殊情況下的時候,還是出現了錯誤。

        那種情況就是如果我們在執行 once 方法之前,就已經通過 off 方法將其移除了。

        我們實現的方法就不能實現這個需求了,所以我們還需要對 once 方法進行一些修改 off 方法已經處理過了)

        添加一個自定義屬性,用來對函數進行 “緩存” 。

        EventEmitter.prototype.once = function (eventName, callBack) {     const one = () => {         // ...     }     one.c = callBack; // 自定義一個屬性     // ... }

        這樣我們就實現了 once 方法。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 精品日韩亚洲AV无码| 精品久久人妻av中文字幕| 无码精品A∨在线观看| 国产精品无码国模私拍视频| 国产精品久线在线观看| 亚洲欧美激情精品一区二区| 久久精品国产精品亚洲人人| 99九九精品免费视频观看| 国产成人精品日本亚洲专一区| 人人妻人人澡人人爽欧美精品 | 精品国产一区二区三区无码| 日本一区二区三区精品国产| 精品久久久久久国产免费了| 成人国产精品日本在线观看| 桃花岛精品亚洲国产成人| 久久精品国产亚洲沈樵| 国产精品污视频| 国产亚洲精品一品区99热| 500av导航大全精品| 99在线精品一区二区三区| 精品国产一区二区三区色欲| 日韩精品无码中文字幕一区二区| 伊人久久大香线蕉精品不卡| 日韩精品国产自在欧美| 欧美国产成人久久精品| 精品水蜜桃久久久久久久| 国产在AJ精品| 精品国产高清在线拍| 精品国产污污免费网站入口| 国产精品天干天干在线综合| 久久精品一本到99热免费| 国产精品9999久久久久| 亚洲AV永久纯肉无码精品动漫| 亚洲精品A在线观看| 人人妻人人澡人人爽人人精品| 国产精品九九九久久九九| 99热精品在线| 欧美国产日本精品一区二区三区 | 四虎成人精品免费影院| 亚洲一二成人精品区| 国产精品爱搞视频网站|