The idea behind the Observer pattern is to create a one-to-many type dependency. When the state of a single object (subject) changes, the objects (observers) dependent on it are notified and updated about it. This is necessary to coordinate the state of interconnected objects without their rigid connectedness.
For example, when changing data A, B, C, the chart and the table responsible for the view must change. At the same time, it is not known how many representations there are.

')
The observer pattern describes how to implement this relationship. It is based on the Subject and Observer objects. The subject changes and notifies the Observers dependent on him about his changes. Observers synchronize their data with the Subject. This relationship is also called a publisher-subscriber. The subject (publisher) sends notifications to its observers (subscribers) without even knowing which objects they are. At the same time, the number of subscribers is unlimited.
How will all this look in Javascript?
Announce publishers
var Microsoft = new Publisher;
var Google = new Publisher;
var Apple = new Publisher;
* This source code was highlighted with Source Code Highlighter .
Now subscribers
var Ann = function (from) {
console.log( 'Delivery from ' +from+ ' to Ann' );
};
var Vasya = function (from) {
console.log( 'Delivery from ' +from+ ' to Vasya' );
};
var Maria = function (from) {
console.log( 'Delivery from ' +from+ ' to Maria ' );
};
* This source code was highlighted with Source Code Highlighter .
Sign all
Ann.subscribe(Microsoft).subscribe(Google).subscribe(Apple);
Vasya.subscribe(Google).subscribe(Apple);
Maria.subscribe(Microsoft);
* This source code was highlighted with Source Code Highlighter .
Send news to subscribers
Microsoft.deliver( 'news 1' ).deliver( 'news 2' );
Google.deliver( 'googlenews 1' ).deliver( 'googlenews 2' );
* This source code was highlighted with Source Code Highlighter .
So, now we will write the designer for the publisher. Subscribers are stored inside it.
function Publisher() {
this .subscribers = [];
}
* This source code was highlighted with Source Code Highlighter .
The publisher method that sends notification to subscribers (forEach extension for arrays can be obtained from developer.mozilla.org)
Publisher.prototype.deliver = function (data) {
this .subscribers.forEach(
function (fn) {
fn(data);
}
);
return this ;
};
* This source code was highlighted with Source Code Highlighter .
And add the subscribe method to the Function to add a subscriber.
Function.prototype.subscribe = function (publisher) {
publisher.subscribers.push( this );
return this ;
};
* This source code was highlighted with Source Code Highlighter .
Here you go. The pattern is ready.
How to use all this?
I will show how to use this pattern to indicate a long-acting process. This action can be processing a large array of data, uploading a file to the server, long movement of any character and, maybe sometime it will be possible in all browsers, processing XHR before the occurrence of readyState = 4.
I will have a panda moving along the path.
Immediately an example .
var Animal= function (id){
this .onGo= new Publisher();
this .id=id;
this .domElement=$( '#' +id);
this .from=parseInt( this .domElement.css( 'left' ));
}
Animal.prototype.go= function (to,duration){
var start = new Date().getTime();
var that= this ;
setTimeout( function () {
var now = ( new Date().getTime()) - start;
var progress = now / duration;
if (progress > 1) progress = 1;
var result = (to - that.from) * progress + that.from;
that.domElement.css( 'left' , result+ 'px' );
that.onGo.deliver(progress);
if (progress < 1)
setTimeout(arguments.callee, 10);
}, 10);
}
...
var Panda= new Animal( 'panda' );
* This source code was highlighted with Source Code Highlighter .
In the constructor, we created the Publisher this.onGo = new Publisher (), and in the method we made a newsletter with the current progress that.onGo.deliver (progress).
It now remains to add observers for the current state of the panda. We show the progress bar and the number of percent of the distance traveled. Obviously, we will make two observers
var Status= function (v){
var per=v*100;
if (per>100)v=100;
$( "#status" ).html((per.toFixed(0))+ "%" )
}
var Bar= function (progress){
var w=(progress*596);
$( "#progressbar" ).css( 'width' ,w+ 'px' );
}
* This source code was highlighted with Source Code Highlighter .
And sign them to the onGo newsletter.
Bar.subscribe(Panda.onGo);
Status.subscribe(Panda.onGo);
* This source code was highlighted with Source Code Highlighter .
Now when the panda moves, the indicators change as well.
As a result, we received three independent objects Bar, Status and Animal, which can be used independently of each other, as well as the ability to quietly add new objects depending on the status of the panda (publisher).
A similar result could be achieved using jquery trigger / bind. Then, instead of a subscription, they would hang bind. And in the method Animal.go added a trigger
example with trigger / bind