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