Source code analysis
On, once and off can all be called in chain mode
on
- In order to
type: [handler]
It’s stored in an instance, so it’s the sametype
Yes you can bind more than onehandler
once
The task is marked as a one-time task that is removed from the array after execution
off
- if
handler
为*
That will betype
Corresponding to allhandler
delete
deleteClears objects directly instead of setting []delete this._event_[ type ]
// undefined
Copy the code
- If you specify
handler
And from themhandlers
If the array length after deletion is 0, it is cleared
emit
- will
handlers
All of thehandler
If marked only once, it is removed from the array when it is finished
for ( let handler of handlers ) { handler.apply( this, args ); if(handler._once_){ onceHandled.push(handler); }}Copy the code
- If there is no corresponding
type
Would go,type
为*
Downgrading scheme of
Why use DELETE rather than delete directly?
! [] // false ! undefined // trueCopy the code
If only a one-time type is cleared, it will be unable to go to the degrade scheme if the type is sent multiple times.
How to match?
So if you say is there a handler in the Handlers?
Due to the incomplete understanding of JS closures and other knowledge, I will skip it temporarily.
pending
Rewrite using swift.
Officially provided Event Bus
registered
Mount a variable above the Vue prototype in main.js
Vue.prototype.Event = new Vue()
Copy the code
The subscriber
When subscribing, be careful to release in time, otherwise it may be executed multiple times
// mounted or any other time
this.Event.$on('xxx'.() = > {})
// onDestroyed or other timing
this.Event.$off('xxx')
Copy the code
The publisher
this.Event.$emit('xxx'.() = > {})
Copy the code
The basic use
The installation
npm i --save event-pubsub
Copy the code
Node
Detailed use of visible official documentation.
var events = new window.EventPubSub();
events.on(
'hello'.function(data){
console.log('hello event recieved ', data);
events.emit(
'world',
{
type:'myObject'.data: {x:'YAY, Objects! '}})}); events.emit('hello'.'world'
);
events.emit(
'hello'.'again'.'and again'
);
Copy the code
The source code
'use strict'; window.EventPubSub=class EventPubSub { constructor( scope ) { this._events_ = {}; this.publish = this.trigger = this.emit; this.subscribe = this.on; this.unSubscribe = this.off; } on( type, handler, once ) { if ( ! handler ) { throw new ReferenceError( 'handler not defined.' ); } if ( ! this._events_[ type ] ) { this._events_[ type ] = []; } if(once){ handler._once_ = once; } this._events_[ type ].push( handler ); return this; } once( type, handler ) { return this.on( type, handler, true ); } off( type, handler ) { if ( ! this._events_[ type ] ) { return this; } if ( ! handler ) { throw new ReferenceError( 'handler not defined. if you wish to remove all handlers from the event please pass "*" as the handler' ); } if ( handler == '*' ) { delete this._events_[ type ]; return this; } const handlers = this._events_[ type ]; while ( handlers.includes( handler ) ) { handlers.splice( handlers.indexOf( handler ), 1 ); } if ( handlers.length < 1 ) { delete this._events_[ type ]; } return this; } emit( type, ... args ) { if ( ! this._events_[ type ] ) { return this.emit$( type, ... args ); } const handlers = this._events_[ type ]; const onceHandled=[]; for ( let handler of handlers ) { handler.apply( this, args ); if(handler._once_){ onceHandled.push(handler); } } for(let handler of onceHandled){ this.off(type,handler); } return this.emit$( type, ... args ); } emit$( type, ... args ) { if ( ! this._events_[ '*' ] ) { return this; } const catchAll = this._events_[ '*' ]; for ( let handler of catchAll ) { handler.call( this, type, ... args ); } return this; } } if (! Array.prototype.includes) { Array.prototype.includes = function(searchElement /*, fromIndex*/) { 'use strict'; if (this == null) { throw new TypeError('Array.prototype.includes called on null or undefined'); } var O = Object(this); var len = parseInt(O.length, 10) || 0; if (len === 0) { return false; } var n = parseInt(arguments[1], 10) || 0; var k; if (n >= 0) { k = n; } else { k = len + n; if (k < 0) {k = 0; } } var currentElement; while (k < len) { currentElement = O[k]; if (searchElement === currentElement || (searchElement ! == searchElement && currentElement ! == currentElement)) { // NaN ! == NaN return true; } k++; } return false; }; }Copy the code