Subscription publishing model
Also called observer mode
case
The subscription-to-publish model is used in many places in VUE, where eventBus is used as a way for components to communicate.
eventBus
class EventBus{
constructor() {// Store all the events and callback arrays in the event object, such as:
// {a: [ ()=>{console.log(1)}, (a)=>{console.log(a)}], b: [()=>{console.log(1)}]}
this.event=Object.create(null);
};
/** Register event * @ Enter event name, corresponding callback function. Undefined * @ adds an array of events and callbacks to the event object. * /
on(name,fn){
if(!this.event[name]){
// An event can have multiple listeners
this.event[name]=[];
};
this.event[name].push(fn);
};
/** trigger event * @ Input the event name name, the rest of the argument (trigger event name corresponding to the callback array, callback function parameters (undefined arguments)). * @ output undefined * @ function triggers the event name corresponding to the callback array */emit(name,... args){// Iterate over the array callback corresponding to the event to fire. Call the functions in the array in turn, passing arguments to each cb.
this.event[name] && this.event[name].forEach(fn= >{ fn(... args) }); };/** only trigger the event * @ input event name, callback function fn * @ output undefined * @ function with cb, at the same time complete the event registration, trigger the event, and finally cancel the event */
once(name,fn){
var cb=(. args) = >{
/ / triggersfn(... args);/ / cancel
this.off(name,fn);
};
/ / to monitor
this.on(name,cb);
};
/** * Cancel event * @ Input event name * @ output undefined * @ function to delete a callback in the specified event name array. * /
off(name,offcb){
if(this.event[name]){
// Find the index of the event to cancel in the callback array
let index=this.event[name].findIndex((fn) = >{
return offcb===fn;
});
// Remove the callback function from the corresponding callback array by index.
this.event[name].splice(index,1);
// When the length of the callback array is 0 (no callback array)
if(!this.event[name].length){
// Delete the event name
delete this.event[name]; }}}}Copy the code
instantiation
var a = new EventBus()
// on emit
a.on('a', () = > {console.log(1)});
a.on('a',(a)=>{console.log(a)});
a.on('b', () = > {console.log(1)});
a.emit('a'.'2'); / / 1. 2
a.emit('b'); / / 1
// The event object is
console.log(a.event);
// {a: [ ()=>{console.log(1)}, (a)=>{console.log(a)}], b: [()=>{console.log(1)}] }
// once
var fnc = (a) = >{console.log(a)};
a.once("d",fnc(1))
// off
var fnc = (a) = >{console.log(a)};
a.on('c',fnc);
a.event; // {a: Array(2), b: Array(1), c: Array(1), d: Array(2)}
a.off("c",fnc);
a.event; // {a: Array(2), b: Array(1), d: Array(2)}
Copy the code
Two-way data binding
This is also done through a subscription publishing model. Of course, there is the crucial data hijacking of Object.defineProperty
To be added
Copy the code
conclusion
- Our Event object, which manages all the events and the corresponding callback array. You can also use a new Map to make it easier to manage
- The whole subscribe publish pattern is to add an array of events and callbacks to the event object. The function in the corresponding callback array is called by the event name.
- Our cases,on, emit,once, and off must all be executed by passing in the event name and callback function name.