Observer model
- In the book javascript Design Patterns, the first sentence of the observer pattern is that the observer pattern is also known as the publish subscriber pattern.
- To be honest, as a design pattern naif, I can’t quite tell whether they are a pattern or not, so let’s start with implementing an observer pattern.
- In the usual development process, used
EventBus
, in fact,EventBus
It’s a practical application of the observer model.
The preliminary implementation
1. Observer mode, need to install a registered event container, here use an object, and then need to subscribe, publish, unsubscribe three methods.
class Observer {
constructor() {
// The subscription container
this.message = {}
}
// Register messages. Subscribe to news
register(name, fn){}
// Publish the message
fire(name,... args){}
// Cancel registration
remove(name,fn){}}Copy the code
- This defines an event handler
message
And subscribing to messagesregister
The event, the announcementfire
Event, unsubscriberemove
Events.
2. Implementregister
Register/subscribe method
// Register messages. Subscribe to news
register(name, fn){
// If there are no events in message to register
if(!this.message.hasOwnProperty(name)){
// Initialize an array and place this time's events in it
// Arrays are used because multiple FN methods may be registered under an event name
this.message[name] = [fn]
}else {
// If already registered, push this method in
this.message[name].push(fn)
}
// Return this because you can make chain calls
return this;
}
Copy the code
3. The implementationfire
Publish message method
// Publish the message
fire(name,... args){
// Get an array of methods under the registration event
const fns = this.message[name]
console.log(fns)
// If there is no corresponding method, throw an exception
if(! fns) {throw new Error('This method is not registered! ')}
// If there is a corresponding event array
// Iterate through the event array and call
fns.forEach(fn= >{
fn.call(this. args) })// Return this because you can make chain calls
return this;
}
Copy the code
4. To achieveremove
Remove subscription methods
// Cancel registration
remove(name,fn){
if(!this.message.hasOwnProperty(name)){
return new Error('No registration method! ')}// Either way is ok
// forEach
// this.message.forEach((item, index) =>{
// if(item === fn) {
// this.message.splice(index, 1)
/ /}
// })
// Method 2: loop && and
// Pass a for loop
for (let i=0; i<fn.length; i++){
this.message[name][i] === fn && this.message[name].splice(i, 1)}// Return this because you can make chain calls
return this;
}
Copy the code
The complete code
class Observer {
constructor() {
this.message = {}
}
// Register messages. Subscribe to news
register(name, fn){
if(!this.message.hasOwnProperty(name)){
this.message[name] = [fn]
}else {
this.message[name].push(fn)
}
return this;
}
// Publish the message
fire(name,... args){
const fns = this.message[name]
console.log(fns)
if(! fns) {throw new Error('This method is not registered! ')}
fns.forEach(fn= >{
fn.call(this. args) })return this;
}
// Cancel registration
remove(name,fn){
if(!this.message.hasOwnProperty(name)){
return new Error('No registration method! ')}// Either way is ok
// this.message.forEach((item, index) =>{
// if(item === fn) {
// this.message.splice(index, 1)
/ /}
// })
// Pass a for loop
for (let i=0; i<fn.length; i++){
this.message[name][i] === fn && this.message[name].splice(i, 1)}return this; }}Copy the code
The test code
function add(a, b){
console.log(a + b )
}
function sub(a, b){
console.log(a - b)
}
const observer = new Observer()
observer.register('add',add) // Register an add method that returns 3
observer.register('sub',sub).fire('sub'.1.2) // Register and publish the sub method, returning -1
observer.fire('hoh'.1) // Publish an unregistered method and throw 'Error: this method is not registered! 'abnormal
Copy the code
Thank you
Reference: javascript Design Patterns, Rongming Zhang
Thank you for your reference, if there is a misunderstanding of the front-end dish chicken, please point out that the younger brother also know their own mistakes, thank you! 🙏