EventBus的實現

mdiep發表於2019-02-16

EventBus概要

EventBus是訊息傳遞的一種方式,基於一個訊息中心,訂閱和釋出訊息的模式。這種方式的實現不僅僅侷限於前端,在iOS中的訊息訊息中心也是如此實現。

  1. 設計模式:訂閱者釋出者模式,這種設計模式在前端很常見。
  2. API的設計:

    2.1 只能構造一個訊息物件

    2.2 on(`msgName`, func)訂閱訊息,msgName:訂閱的訊息名稱 func: 訂閱的訊息

    2.3 one(`msgName`, func)僅訂閱一次訊息,後訂閱的會替換前面訂閱的訊息

    2.4 emit(`msgName`, msg)釋出訊息 msgName:訊息名稱 msg:釋出的訊息

    2.5 off(`msgName`)移除訊息

實現EventBus

// 構造EventBus
function EventBusClass() {
    this.msgQueues = {}
}

EventBusClass.prototype = {
    // 將訊息儲存到當前的訊息佇列中
    on: function(msgName, func) {
        if (this.msgQueues.hasOwnProperty(msgName)) {
            if (typeof this.msgQueues[msgName] === `function`) {
                this.msgQueues[msgName] = [this.msgQueues[msgName], func]                
            } else {
                this.msgQueues[msgName] = [...this.msgQueues[msgName], func]    
            }
        } else {
            this.msgQueues[msgName] = func;
        }
    },
    // 訊息佇列中僅儲存一個訊息
    one: function(msgName, func) {
        // 無需檢查msgName是否存在
        this.msgQueues[msgName] = func;
    },
    // 傳送訊息
    emit: function(msgName, msg) {
        if (!this.msgQueues.hasOwnProperty(msgName)) {
            return
        }
        if (typeof this.msgQueues[msgName] === `function`) {
            this.msgQueues[msgName](msg)
        } else {
            this.msgQueues[msgName].map((fn) => {
                fn(msg)
            })
        }
    },
    // 移除訊息
    off: function(msgName) {
        if (!this.msgQueues.hasOwnProperty(msgName)) {
            return
        }
        delete this.msgQueues[msgName]
    }
}

// 將EventBus放到window物件中
const EventBus = new EventBusClass()
window.EventBus = EventBus

使用EventBus

// 訂閱訊息
function subscribe() {
    EventBus.on(`first-event`, function(msg) {
        alert(`訂閱的訊息是:${msg}`);
    });
}

// 傳送訊息
function emit() {
    const msgInput = document.getElementById("msgInputId")
    EventBus.emit(`first-event`, msgInput.value)
}

// 移除訊息
function off(msgName) {
    EventBus.off(msgName)
}

CodePen預覽

CodePen預覽

—–可能需要翻牆—–

<p data-height=”265″ data-theme-id=”0″ data-slug-hash=”maQpgR” data-default-tab=”js,result” data-user=”beyondverage0908″ data-pen-title=”EventBus的實現” style=”height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;” class=”codepen”><span>See the Pen EventBus的實現 by avg (@beyondverage0908) on CodePen.</span></p>
<script async src=”https://static.codepen.io/ass…;></script>

總結

整個EventBus主要部分是分為三個部分。訊息中心,訂閱事件方法,釋出訊息方法。雖然不能和Vue中實現的那麼全面,但麻雀雖小,五臟俱全。缺少的部分在於對資料安全性的校驗。希望給你一個實現的思路

相關文章