Using JavaScript to implement simple EventBus

What is EventBus?

  • event bus refers to the bus

    Using a fixed bus stop to handle boarding and alighting events is compared to subscription and event distribution

  • In programming, eventbus is usually used to transmit data in the form of publish and subscribe

    Subscribe to events in advance. When events are triggered, you can receive data related to large events

  • How

    Basic knowledge required

    Prototype object and prototype chain, callback function

    Basic implementation ideas:

    1. The constructor or class is used to store the information of the subscriber and the event

    2. Add publish and subscribe methods on the prototype of this class / constructor

      • The published method needs to be passed in. The event name to be published and the event data are used as parameters

      • The subscription method needs to pass in the name of the subscribed event and the event handler (callback function)

    3. The main process is to call the subscription method on the prototype chain through the instance of the constructor, and the event and method of the incoming subscription are stored in the corresponding attribute of the instance (map is used here) - the message publisher. Through the incoming event name, take out the subscription function previously passed in from the instance data, call it, and pass in the published information content at the same time

    Implementation method: Here we use the syntax of the constructor class

     class _EventBus {
       constructor() {
         //When instantiated_ Instance properties within the constructor when EventBus
         this._events = new Map() //Here, the k-v of the map is used to store the event name - the corresponding subscriber information
         //There is a prototype attribute in the constructor, which points to the constructor, 
         //Therefore, methods on prototype can access properties on instances
       }
     }

    Next, we add a publisher method to the prototype object

     // release 
     //type is the name of the published information
     //... Args is the published information content, which means that multiple can be received and will eventually be stored in args in the form of array
     _EventBus.prototype.myPub = function (type, ...args) {
       //Get the corresponding subscribers according to the published event name (we use array form here to have multiple subscribers)
       let subEvents = this._events.get(type)
       //If so, traverse all subscriber information and call the subscriber's method to publish the information
       //Note: information will be published to all subscribers of the same information, 
       //If customization is needed, the subscriber can be uniquely identified and used as the search condition for publishing (that is, another layer of map can be nested)
       if (subEvents) {
         //len is used here to reduce the dynamic fetch array length
         for (let i = 0, len = subEvents.length; i < len; i++) {
           if (args.length > 2) { //If more than two parameters are passed in, we use apply
             subEvents[i].apply(this, args) //Use apply to pass in the array directly
           } else {
             subEvents[i].call(this, ...args) //Use call to disperse in place
             //(Note: if there are deep-seated objects in the array, only shallow copies can be implemented here)
           }
         }
       } else { //If there is no such event, add one and the subscriber is null
         this._events.set(type, null)
       }
     }

    Here's how to add a subscription to the prototype

     // subscribe
     //type is the name of the published information
     //When subEvent is a subscription, the processing function (callback function) in the re instance property is stored, which will be executed when publishing
     _EventBus.prototype.mySub = function (type, subEvent) {
       //Get the processing of type. If not, add the subscription
       const subEvents = this._events.get(type)
       if (!subEvents) {
         //If the type event does not have a corresponding publishing method, the subscription method is passed to the publisher
         //This is in the form of an array if there are multiple subscribers
         this._events.set(type, [subEvent])
       } else {
         subEvents.push(subEvent) // If there are already subscribers, they will be added directly
       }
       return subEvent //Returning this method to the most used will remove the specified subscriber
     }

    The following can be used simply

     // instantiation 
     const _eb = new _EventBus()
     // subscribe
     //The number of parameters is the same as the published ones (the received introduction is omitted, and the undefined is displayed)
     _eb.mySub('eventName', (n1, n2, n3) => {
       console.log(n1, n2, n3)
     })
     _eb.mySub('evebtAge', age => {
       console.log(`Age received is ${age}`)
     })
     ​
     // Release news
     _eb.myPub('eventName', 'Tom', 'Jerry', 'Tang') //Tom Jerry Tang
     _eb.myPub('evebtAge', 18) //The age received is 18

    Let's try to delete the subscription event

     //Remove subscription
     //subEvent is returned when calling the subscription function mySub. The function ontology is passed in. We need to find it and delete it
     _EventBus.prototype.removeSub = function (type, subEvent) {
       //Get all subscriber information of the corresponding message
       const subEvents = this._events.get(type)
       // Traverse to find the corresponding subEvent and delete it
       for (let i = 0, len = subEvents.length; i < len; i++) {
         if (subEvents[i] === subEvent) { //If the return value of mySub is directly received using the defined variable, it is congruent here
           subEvents.splice(i, 1) //Starting from i, delete 1
           return true //end
         }
       }
     }

    The above is my general understanding of the event publish subscribe mechanism. If there is any error, please give me some advice

    Attach an example of my Muggle, which can be used directly. You can see the use in Vue at a glance

    https://github.com/zdShi/da-event-bus

Reference article:

Interviewer: since React/Vue can use Event Bus for component communication, can you implement it- Nuggets

Keywords: Javascript Front-end

Added by Hitch54 on Sat, 15 Jan 2022 00:48:33 +0200