Ein EventBus mit JavaScript erstellen

JavaScript

Github Code

Was ist ein EventBus?

Nehmen wir als Beispiel ein Button-Klick. Im Quellcode definieren wir einen Event-Trigger, der ausgelöst werden soll, sobald der Benutzer einen bestimmten Button anklickt. Zum Beispiel könnte sich auf dem Button-Klick ein Modalfenster öffnen in dem er zusätzliche Informationen zu einem Produkt erhält. In einem anderen Teil des Quellcodes definieren wir einen Event-Handler der das Event im EventBus registriert und genau dann ausgelöst wird, sobald der Event-Trigger feuert.

Der EventBus agiert praktisch als Vermittler zwischen den verschiedenen Teilen der Applikation. Je größer eine Applikation ist, desto wichtiger ist eine funktionerende Kommunikation ihrer Komponenten untereinander. Ein Event-System ist dabei oft eine gute Wahl. Wenn der Event-Mechanismus eine Vielzahl von Grundelementen einer Anwendung wie zum Beispiel die Business-Logik oder die Benutzersteuerung umfasst, spricht man von einer Event-driven Anwendung. Viele Frameworks basieren auf diesem Prinzip. Dabei spielt es keine Rolle ob Events von Komponenten, einzelnen JavaScript-Klassen oder zur Laufzeit von bestimmten Benutzereingaben ausgelöst werden. Ein EventBus lässt sich universell einsetzen. Und genau das ist der Vorteil. Die Flexibilität spielt eine wichtige Rolle. Aber auch die geringe Komplexität. Ein EventBus-Mechansimus ist in der Regel einfach aufgebaut und leicht zu verstehen.

Aufbau einer EventBus-Klasse mit JavaScript

Es gibt verschiedene Ansätze wie ein EventBus implementiert werden kann. Im Internet findet man dazu unzählige Varianten für die verschiedensten Programmiersprachen. In unserem Beispiel wollen wir es möglichst einfach halten. Wir erstellen eine JavaScript-Klasse EventBus die wir als Singleton definieren. Es gibt immer exakt eine Instanz der EventBus-Klasse und diese wird direkt im new EventBus() exportiert. Damit existiert genau eine Instanz des EventBus. Das ist wichtig damit alle registrierten Events in der selben Klasseninstanz landen.

Innerhalb der Klasse definieren die Methode on(). Das ist der Event-Handler mit dem wir Callback-Funktionen auf ein bestimmtes Event registrieren können. Die Methode trigger() führt die Callback-Funktionen eines bestimmten Events aus, sobald es gefeuert wird. Das ist im Prinzip schon alles.


let instance;

/**
 * Simple Event Handler class
 * Handles app wide events to use for multiple components
 * Acts as a singleton pattern
 */
class EventBus {
    constructor() {
        if (!instance) {
            instance = this;
        }
        this.eventList = {};
        return instance;
    }

    /**
     * Register a callback function to a certain event
     */
    on(eventName, callback) {
        let listener = {
            callback: callback,
        };

        this.eventList[eventName] = this.eventList[eventName] || [];
        this.eventList[eventName].push(listener);
    }

    /**
     * Trigger a certain Event
     */
    trigger(eventName, arg) {
        try {
            arg = arg || {};
            const eventListeners = this.eventList[eventName] || [];
            eventListeners.forEach((listener) => {
                listener.callback(arg);
            });
        } catch(e) {
            console.log(e);
        }
    }
}

// export the class as a new instance
export default new EventBus()

Wofür lässt sich ein EventBus nutzen?

Es gibt zwei Events. APP_INITIALIZED wird getriggert wenn die Anwendung geladen wird. Genauer gesagt wenn die Klasse App initialisiert wird. Ein zweites Event BUTTON_CLICKED wird mit dem Klick-Handler des Button verbunden. Dieses Event wird zur Laufzeit hinzugefügt und genau dann ausgeführt, wenn jemand auf den Button klickt.


import EventBus from './EventBus.js';

class App {
    constructor() {
        const button = document.getElementById('button');
    }
    init() {

        button.addEventListener('click', (e) => {
            EventBus.trigger('BUTTON_CLICKED', e);
        });

        EventBus.trigger('APP_INITIALIZED', ({ data }) => {
            console.log(`The application has been initialized`);
        });
    }
}

window.App = new App();
window.App.init();

EventBus.on('BUTTON_CLICKED', ({ data }) => {
    console.log(`The application has been initialized`);
});

Der EventBus lässt sich zum Beispiel im Zusammenspiel mit einem JavaScript Proxy nutzen um Reaktivität zu erzeugen. Mehr dazu gibt es hier Reaktivität mit JavaScript Proxy



Artikel teilen