JavaScript Design patterns and development Practices---reading notes (8) Publish-Subscribe mode

Source: Internet
Author: User

The Publish-subscribe pattern is also called the Observer pattern, which defines a one-to-many dependency between objects, and when an object's state changes, all objects that depend on it are notified.

The publish-subscribe pattern can be widely used in asynchronous programming, which is an alternative to the transitive callback function.

Can replace the hard-coded notification mechanism between objects, and an object does not have to explicitly invoke an interface of another object.

Custom events

    1. Start by specifying who will act as the publisher;
    2. Then add a cache list to the publisher to hold the callback function to inform the subscribers;
    3. When the message is last published, the publisher iterates through the cache list, triggering the subscriber callback function that is placed inside.

Also, we can fill in some parameters in the callback function, and subscribers can receive these parameters.

The simplest publish-subscribe mode:

varSalesoffices = {};//Define sales OfficeSalesoffices.clientlist = [];//cache list, which holds subscribers ' callback functionsSalesoffices.listen =function(FN) {//Add Subscribers         This. Clientlist.push (FN);//subscribed messages are added to the cache list    }; Salesoffices.trigger=function(){//Release Mode         for(varI=0,FN;FN = This. clientlist[i++]; ) {fn.apply ( This, arguments);//arguments is the parameter that is taken when the message is published        }    }; Salesoffices.listen (function(Price,squaremeter) {//xiaoming Subscription MessageConsole.log (' Price = ' +Price ); Console.log (' Squaremeter= ' +squaremeter);    }); Salesoffices.listen (function(Price,squaremeter) {//Little Red Subscribe messageConsole.log (' Price = ' +Price ); Console.log (' Squaremeter= ' +squaremeter);    }); Salesoffices.trigger (2000000,88);//output: 2 million, 88 sqmSalesoffices.trigger (3000000,110);//output: 3 million, 110 sqm

Let subscribers subscribe only to messages of interest to them:

    varSalesoffices = {};//Define sales OfficeSalesoffices.clientlist = [];//cache list, which holds subscribers ' callback functionsSalesoffices.listen =function(KEY,FN) {if(! This. Clientlist[key]) {//If you have not subscribed to such a message, create a cache list for the class message             This. Clientlist[key] = []; }         This. Clientlist.push (FN);//subscribed messages are added to the cache list    }; Salesoffices.trigger=function(){//Publish a message        varKey = Array.prototype.shift.call (arguments),//Remove Message TypeFNS = This. Clientlist[key];//Remove the callback function collection for the message        if(!fns | | fns.length ===0) {//If the message is not subscribed, it returns            return false;        };  for(varI=0,FN;FN = This. clientlist[i++]; ) {fn.apply ( This, arguments);//arguments is the parameter that comes with when you publish a message        }    }; Salesoffices.listen (' SquareMeter88 ',function(Price) {//Xiaoming subscribed to 88 messageConsole.log (' Price = ' +Price );    }); Salesoffices.listen (' SquareMeter110 ',function(Price) {//Little Red Subscription 110 messageConsole.log (' Price = ' +Price );    }); Salesoffices.trigger (' SquareMeter88 ', 88); Salesoffices.trigger (' squareMeter110 ', 110);

Common implementations:

//Publish-Subscribe feature    varevent ={clientlist:[], listen:function(KEY,FN) {if(! This. Clientlist[key]) {                 This. Clientlist[key] = []; }             This. Clientlist[key].push (FN);//subscribed messages are added to the cache list}, Trigger:function(){            varKey =Array.prototype.shift.call (arguments), FNS= This. Clientlist[key]; if(!fns | | fns.length ===0) {//if the corresponding message is not bound                return false; }             for(varI =0, FN;FN = fns[i++]; ) {fn.apply ( This. arguments);//arguments is the parameter on the trigger.            }        }    };//dynamically installs the Publish-subscribe feature for all objects    varInstallevent =function(obj) { for(varIinchevent) {Obj[i]=Event[i];    }    }; varSalesoffices = {};    Installevent (salesoffices); Salesoffices.listen (' SquareMeter88 ',function(Price) {//xiaoming Subscription MessageConsole.log (' Price = ' +Price );    }); Salesoffices.listen (' SquareMeter110 ',function(Price) {//Little Red Subscribe messageConsole.log (' Price = ' +Price );    }); Salesoffices.trigger (' SquareMeter88 ', 2000000); Salesoffices.trigger (' squareMeter110 ', 3000000);

To unsubscribe from events:

//Unsubscribe from EventsEvent.remove =function(KEY,FN) {varFNS = This. Clientlist[key]if(!FNS) {//if the message corresponding to key is not subscribed to, it is returned directly            return false; }        if(!FN) {//if no specific callback function is passed, all subscriptions that need to cancel the key corresponding messagefns&& (fns.length = 0); }Else{             for(varL = fns.length-1;l>=0;l--) {//List of callback functions for reverse traversal subscriptions                var_FN =Fns[l]; if(_FN = = =fn) {Fns.splice (L,1);//remove a subscriber's callback function                }            }        }        }; varSalesoffices = {}; varInstallevent =function(obj) { for(varIinchevent) {Obj[i]=Event[i];    }} installevent (Salesoffices); Salesoffices.listen (' SquareMeter88 ', fn1=function(Price) {//xiaoming Subscription MessageConsole.log (' Price = ' +Price );    }); Salesoffices.listen (' squareMeter110 ', fn2=function(Price) {//Little Red Subscribe messageConsole.log (' Price = ' +Price );    }); Salesoffices.remove (' SquareMeter88 ', FN1); Salesoffices.trigger (' squareMeter110 ', 2000000);

Global Publish-Subscribe mode:

The publish-subscribe pattern can be implemented with a global event object that the Subscriber does not need to know clearly from which publisher, the Publisher does not know which subscribers the message will be pushed to, and the event acts as a "mediator" role, linking subscribers and publishers.

varEvent = (function(){        varClientlist ={}, listen, trigger, remove; Listen=function(KEY,FN) {if(!Clientlist[key]) {Clientlist[key]= [];        } clientlist[key].push (FN);        }; Trigger=function(){            varKey =Array.prototype.shift.call (arguments), FNS=Clientlist[key]; if(!fns| | Fns.length===0){                    return false; }                 for(vari=0,fn;fn=fns[i++]; ) {fn.apply ( This, arguments);        }        }; Remove=function(KEY,FN) {varFNS =Clientlist[key]; if(!FNS) {                return false; }            if(!fn) {FNS&& (fns.length = 0); }Else{                 for(varl=fns.length-1;l>=0;l--){                    var_FN =Fns[l]; if(_FN = = =fn) {Fns.splice (L,1);        }                }            }        }; return{listen:listen, Trigger:trigger, Remove:remove}})    (); Event.listen (' SquareMeter88 ',function(Price) {Console.log (' Price = ' +Price );    }); Event.trigger (' squareMeter88 ', 2000000);

Inter-module communication:

<! DOCTYPE html>varA = (function(){        varCount = 0; varbutton = document.getElementById (' Count '); Button.Click=function() {Event.trigger (' Add ', count++);    }    })(); varB = (function(){        vardiv = document.getElementById (' Show '); Event.listen (' Add ',function(count) {div.innerhtml=count;    }); })();</script>

Do I have to subscribe and republish?

In some cases, we need to save this message first, and then post the message to the Subscriber when there is an object to subscribe to it.

Naming conflicts for global events:

Provides the event object with the ability to create a namespace.

In JavaScript, we replace the traditional publish-subscribe pattern with the form of a registered callback function, which is more elegant and simple.

The advantages of the publish-subscribe model are obvious, one-time decoupling, and two decoupling on the object.

JavaScript Design patterns and development Practices---reading notes (8) Publish-Subscribe mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.