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, usedEventBus, in fact,EventBusIt’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 handlermessageAnd subscribing to messagesregisterThe event, the announcementfireEvent, unsubscriberemoveEvents.

2. ImplementregisterRegister/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 implementationfirePublish 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 achieveremoveRemove 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! 🙏