This is the second day of my participation in the August More text Challenge. For details, see:August is more challenging

The published-subscribe mode listens for the callback of the on dispatch emit function

  • Those who have used vueBus know about the ON binding and using emit to trigger the vueBus.

The rough code is:

const vueBus = new Vue();

// Bind jue-jin with $on
vueBus.$on('jue-jin'.() = > {
 console.log('I'm the nugget')});// Use $emit to trigger a callback for the jue-jin binding
vueBus.$emit('jue-jin')

// Use $off to unbind
vueBus.$off('jue-jin')


// Unbind when the once binding is triggered once
vueBus.$once('jue-jin-once'.() = > {
 console.log('I'm a gold nugget once')});Copy the code
  • There are four methods: on, emit, once and off

Let’s implement our own publish and subscribe model;

start

  • Let’s define a function called EventEmitter
  • Events is a way to store our subscriptions
//

class EventEmitter {
  constructor() {
    this.events = {}
  }
}
Copy the code

on

  • On function determines parameters (2)
  • Parameter 1 String
  • Argument 2 function callback function
  • {[kay: String(parameter 1)]: [function(parameter 2)]}
  • The whole point of having an array of values is that you can bind a key multiple times in different places
  • Function: Bind events

The parameters are confirmed so let’s try to write it down

class EventEmitter {
   constructor() {
     this.events = {}
   }
   @params {String} eventName *@params {Function} cb */
   on(eventName, cb) {
     // Put the binding in events
     if(this.events[eventName]) {
       // Push the binding
       this.events[eventName].push(cb)
     } else {
     // The unbound function is defined as an array type, and the function is placed inside the array
      this.events[eventName] = [cb]
     }
   }
 }
Copy the code

Now that the binding is written, let’s write the emit to trigger the callback to the on binding

emit

  • Determine two parameters
  • Parameter 1 String is the key bound to on
  • Parameter 2 is the parameter that we emit when we emit
  • Run the following command to trigger the callback CB of the corresponding key

Let’s try to write this function

class EventEmitter {
   constructor() {
     this.events = {}
   }
   @params {String} eventName *@params {Function} cb */
   on(eventName, cb) {
     // Put the binding in events
     if(this.events[eventName]) {
       // Push the binding
       this.events[eventName].push(cb)
     } else {
     // The unbound function is defined as an array type, and the function is placed inside the array
      this.events[eventName] = [cb]
     }
   }
   
   emit(eventName, ... args) {
    [] {key: []}
    //forEach loop call
    / / parameters args
     this.events[eventName] && this.events[eventName].forEach(cb= > {
      cb(...args);
     });
   }
   
 }
Copy the code

So I’m going to write a little demo here to verify that we’re doing all right

Try to verify that

//new a function class we just wrote
const myEvent = new EventEmitter();

/ / binding
myEvent.on('jue-jin-event'.(params) = > {
 console.log(params, 'Gold Mining Community')});/ / triggers

myEvent.emit('jue-jin-event'.'I am a member of the Gold digger community, and this is the samhara custom publisher-subscribe, reader-mode')

// Output: I am a member of the Mining community, this is the three original custom publishing order, reader mode mining community
Copy the code

Verification by

  • Verify that I am a member of the Mining community through output, which is the three original custom publishing order, reader mode mining community
  • Next we write the off unbinding event

off

  • Determine one parameter
  • Parameter 1 is the key we want to unbind
  • Run the following command to unbind and release a binding
class EventEmitter {
   constructor() {
     this.events = {}
   }
   @params {String} eventName *@params {Function} cb */
   on(eventName, cb) {
     // Put the binding in events
     if(this.events[eventName]) {
       // Push the binding
       this.events[eventName].push(cb)
     } else {
     // The unbound function is defined as an array type, and the function is placed inside the array
      this.events[eventName] = [cb]
     }
   }
   
   emit(eventName, ... args) {
    [] {key: []}
    //forEach loop call
    / / parameters args
     this.events[eventName] && this.events[eventName].forEach(cb= >{ cb(... args); }); }off(eventName) {
    if(this.events[eventName]) {
     delete this.events[eventName]
    }
   }
 }
Copy the code

Off to verify

myEvent.on('off-test'.(params) = > {
 console.log(params, 'Gold Mining Community')}); myEvent.emit('off-test'.'I am an unbound off-test');

myEvent.off('off-test');

myEvent.emit('off-test'.'I'm unbinding off');

// Output: I am unbound off-test
Copy the code

Off Verification succeeds

  • Off Verification succeeds

once

  • The two parameters are determined just like the on function
  • Function: can only call once to unbind;

Let’s try to write it as follows

class EventEmitter {
   constructor() {
     this.events = {}
   }
   @params {String} eventName *@params {Function} cb */
   on(eventName, cb) {
     // Put the binding in events
     if(this.events[eventName]) {
       // Push the binding
       this.events[eventName].push(cb)
     } else {
     // The unbound function is defined as an array type, and the function is placed inside the array
      this.events[eventName] = [cb]
     }
   }
   
   emit(eventName, ... args) {
    [] {key: []}
    //forEach loop call
    / / parameters args
     this.events[eventName] && this.events[eventName].forEach(cb= >{ cb(... args); }); }off(eventName) {
    if(this.events[eventName]) {
     delete this.events[eventName]
    }
   }
   
   once(eventName, cb) {
     // Unbind the binding immediately if it can only be triggered once
     // Define a function
     // Functions include calling the cb callback and unbinding
     
     const once = (. args) = >{ cb(... args)this.off(eventName)
     }
     / / binding
     this.on(eventName, once)
   }
 }
Copy the code

Once authentication

myEvent.once('once-test'.(params) = > {
 console.log(params, 'Gold Mining Community')}); myEvent.emit('once-test'.'I called once-test for the first time');

myEvent.emit('once-test'.'I'm calling once-test the second time.');
// Output: I'm the first call to the once-test mining community
Copy the code

Once verification succeeds

  • Verification by

Practical scenario

There are a lot of usage scenarios

  • It can help you interact with the people using the plugin while you’re writing it
  • You just need to inherit the function to become (usage)
class CustomClass  extends events {
  constructor() {
   super()}init() {
    this.emit('extends-events'.'I'm using a plugin from a publishing subscriber ~~~~~~')}}const customClass = new CustomClass();
/ / binding
customClass.on('extends-events'.(params) = > {
   console.log(params, 'Gold Mining Community')
})

customClass.init();
// Output: I am using the plugin for publishing subscribers oh ~~~~~~ the nugget community
Copy the code

conclusion

  • Hello, I’m Sanyuan
  • Thank you for watching. I hope it helps you
  • If you have problems, you can point them out. Let’s communicate together

Source code: posted later

TS version of the need to directly copy

type callBack = (arg? :any) = > void 


class EventEmitter {
    _events: { [key: string] :any };
    
    constructor() {
        this._events = {}
    }

    public on(eventName: string.cb: callBack): void {
        if (this._events[eventName]) {
            this._events[eventName].push(cb);
        } else {
            this._events[eventName] = [cb]; }}public emit(eventName: string. args:any) :void {
       this._events[eventName] && this._events[eventName].forEach((fn: callBack) = >{ fn(... args); }); }public off(eventName: string.cb: callBack): void {
        if (this._events && this._events[eventName]) {
            delete this._events[eventName]
        }
    }

    public once(eventName: string.cb: callBack): void {
        const one = () = > {
            cb();
            this.off(eventName, one);
        };

        this.on(eventName, one); }}export default EventEmitter;

Copy the code