The observer mode (also known as the publisher-subscriber mode) should be one of the most commonly used modes. It is widely used in many languages, including the dom events we usually contact. It is also an observer mode implemented between js and dom.
The code copy is as follows:
div.onclick = function click (){
alert ( "click' )
}
As long as you subscribe to the click event of the div, the function click will be triggered.
So what is the observer mode? Let’s take a look at the observer mode in life.
There is a famous saying in Hollywood. "Don't call me, I'll call you." This sentence explains the ins and outs of an observer pattern. Among them, "I" is the publisher and "you" is the subscriber.
Let me give you another example. When I came to the company for an interview, every interviewer would say to me after I finished: "Please leave your contact information, and we will notify you if there is any news." Here "I" is the subscriber and the interviewer is the publisher. So I don’t have to ask about the interview results every day or every hour, and the initiative in communication is in the hands of the interviewer. And I just need to provide a contact information.
The observer mode can achieve decoupling between the two modules very well. If I was developing an html5 game on a team, when the game started, some image material needed to be loaded. The game logic is executed only after loading these images. Suppose this is a project that requires multiple people to work with. I completed the Gamer and Map modules, and my colleague A wrote an image loader loadImage.
The code of loadImage is as follows:
The code copy is as follows:
loadImage( imgAry, function(){
Map.init();
Gamer.init();
} )
When the image is loaded, the map is rendered and the game logic is executed. Well, the program is running well. Suddenly one day, I remembered that I should add a sound function to the game. I should have the image loader add a line of code.
The code copy is as follows:
loadImage( imgAry, function(){
Map.init();
Gamer.init();
Sount.init();
} )
But my colleague A, who wrote this module, went on a trip abroad. So I called him, hey. Where is your loadImage function? Can I change it? Will there be any side effects after it is changed? As you think, all kinds of uneasy things happened. If we could write this way at the beginning:
The code copy is as follows:
loadImage.listen( "ready', function(){
Map.init();
})
loadImage.listen( "ready', function(){
Gamer.init();
})
loadImage.listen( "ready', function(){
Sount.init();
})
After loadImage is completed, it doesn't care about what will happen in the future, because its work is done. Next it just publishes a signal.
The code copy is as follows:
loadImage.trigger( "ready' );
Then the subjects who listened to the 'ready' event of loadImage will receive notifications. Just like the last interview example. The interviewer does not care about where the interviewers will eat after receiving the interview results. He is only responsible for collecting the interviewers' resumes together. When the interview results come out, they will notify them one by one according to the phone number on the resume.
After talking about so many concepts, we can achieve a specific implementation. The implementation process is actually very simple. The interviewer throws the resume into a box, and then the interviewer calls one by one to notify the results at the right time.
The code copy is as follows:
Events = function() {
var listen, log, obj, one, remove, trigger, __this;
obj = {};
__this = this;
listen = function( key, eventfn ) { // Throw the resume in the box, key is the contact information.
var stack, _ref; //stack is a box
stack = ( _ref = obj[key] ) != null ? _ref : obj[ key ] = [];
return stack.push( eventfn );
};
one = function( key, eventfn ) {
remove( key );
return listen( key, eventfn );
};
remove = function( key ) {
var _ref;
return ( _ref = obj[key] ) != null ? _ref.length = 0 : void 0;
};
trigger = function() { //The interviewer calls to notify the interviewer
var fn, stack, _i, _len, _ref, key;
key = Array.prototype.shift.call( arguments );
stack = ( _ref = obj[ key ] ) != null ? _ref : obj[ key ] = [];
for ( _i = 0, _len = stack.length; _i < _len; _i++ ) {
fn = stack[ _i ];
if ( fn.apply( __this, arguments ) === false) {
return false;
}
}
return {
listen: listen,
one: one,
remove: remove,
trigger: trigger
}
}
Finally, use the Observer mode to make a small application for adult TV stations.
The code copy is as follows:
//Subscribers
var adultTv = Event();
adultTv .listen( "play', function( data ){
alert ("Whose movie is today" + data.name );
});
//Publisher
adultTv .trigger( "play', { 'name': 'Ki Aso' } )