首頁  >  文章  >  web前端  >  Node.js學習之聊Events模組

Node.js學習之聊Events模組

青灯夜游
青灯夜游轉載
2021-12-24 18:18:274177瀏覽

本篇文章帶大家了解一下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  方法。

更多node相關知識,請造訪:nodejs 教學! !

以上是Node.js學習之聊Events模組的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除