Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erläuterung der Beispiele für JavaScript-Beobachtermuster

Ausführliche Erläuterung der Beispiele für JavaScript-Beobachtermuster

小云云
小云云Original
2018-01-22 09:44:322270Durchsuche

Dieser Artikel stellt das Observer-Muster vor, ein JavaScript-Programmierentwurfsmuster. Er erläutert kurz das Konzept und die Prinzipien des Observer-Musters und bietet detaillierte Implementierungs- und Verwendungsfähigkeiten des Observer-Musters in Form von Beispielen Ich kann darauf verweisen, ich hoffe, es kann jedem helfen.

Einführung

Eine einfache Erklärung des Beobachtermusters besteht darin, dass ein Objekt (Subjekt) eine Liste von Objekten (Beobachtern) verwaltet, von denen es abhängt Wenn sich der eigene Zustand ändert, werden alle Beobachterobjekte automatisch benachrichtigt. Wenn ein Objekt nicht benachrichtigt werden muss, kann es aus der Objektliste gelöscht werden.

Aus der obigen Erklärung können wir drei Komponenten extrahieren: Subject, ObserverList und Observer. Die Implementierung mit JS ist sehr einfach:


function ObserverList(){
 this.observerList = [];
}
ObserverList.prototype.Add = function( obj ){
 return this.observerList.push( obj );
};
ObserverList.prototype.Empty = function(){
 this.observerList = [];
};
ObserverList.prototype.Count = function(){
 return this.observerList.length;
};
ObserverList.prototype.Get = function( index ){
 if( index > -1 && index < this.observerList.length ){
  return this.observerList[ index ];
 }
};
ObserverList.prototype.Insert = function( obj, index ){
 var pointer = -1;
 if( index === 0 ){
  this.observerList.unshift( obj );
  pointer = index;
 }else if( index === this.observerList.length ){
  this.observerList.push( obj );
  pointer = index;
 }
 return pointer;
};
ObserverList.prototype.IndexOf = function( obj, startIndex ){
 var i = startIndex, pointer = -1;
 while( i < this.observerList.length ){
  if( this.observerList[i] === obj ){
   pointer = i;
  }
  i++;
 }
 return pointer;
};
ObserverList.prototype.RemoveAt = function( index ){
 if( index === 0 ){
  this.observerList.shift();
 }else if( index === this.observerList.length -1 ){
  this.observerList.pop();
 }
};
// Extend an object with an extension
function extend( extension, obj ){
 for ( var key in extension ){
  obj[key] = extension[key];
 }
}

Subject Sie haben die Möglichkeit, Beobachter hinzuzufügen und zu löschen


function Subject(){
 this.observers = new ObserverList();
}
Subject.prototype.AddObserver = function( observer ){
 this.observers.Add( observer );
};
Subject.prototype.RemoveObserver = function( observer ){
 this.observers.RemoveAt( this.observers.IndexOf( observer, 0 ) );
};
Subject.prototype.Notify = function( context ){
 var observerCount = this.observers.Count();
 for(var i=0; i < observerCount; i++){
  this.observers.Get(i).Update( context );
 }
};

Definieren Sie abschließend ein Beobachterobjekt und implementieren Sie die Aktualisierungsmethode


// The Observer
function Observer(){
 this.Update = function(){
  // ...
 };
}

Wenn mehrere Beobachter vorhanden sind, erweitern Sie einfach das obige Basisobjekt und überschreiben Sie die Update-Methode.

Obwohl das Observer-Muster weit verbreitet ist, werden in JS häufig Variationen davon verwendet: Publish-Subscribe-Muster

Das Publish-Subscribe-Muster entkoppelt das Observer-Muster über einen Themen-/Ereigniskanal. Die Kopplung Das Problem zwischen Betreff (Herausgeber) und Beobachter (Abonnent) wird in JS häufig verwendet.

Das folgende einfache Beispiel veranschaulicht die Grundstruktur der Verwendung des Publish-Subscribe-Musters


// A very simple new mail handler
// A count of the number of messages received
var mailCounter = 0;
// Initialize subscribers that will listen out for a topic
// with the name "inbox/newMessage".
// Render a preview of new messages
var subscriber1 = subscribe( "inbox/newMessage", function( topic, data ) {
 // Log the topic for debugging purposes
 console.log( "A new message was received: ", topic );
 // Use the data that was passed from our subject
 // to display a message preview to the user
 $( ".messageSender" ).html( data.sender );
 $( ".messagePreview" ).html( data.body );
});
// Here&#39;s another subscriber using the same data to perform
// a different task.
// Update the counter displaying the number of new
// messages received via the publisher
var subscriber2 = subscribe( "inbox/newMessage", function( topic, data ) {
 $(&#39;.newMessageCounter&#39;).html( mailCounter++ );
});
publish( "inbox/newMessage", [{
 sender:"hello@google.com",
 body: "Hey there! How are you doing today?"
}]);
// We could then at a later point unsubscribe our subscribers
// from receiving any new topic notifications as follows:
// unsubscribe( subscriber1, );
// unsubscribe( subscriber2 );

Implementierung des Publish-Subscribe-Musters Abonnementmuster

Viele Js-Bibliotheken haben das Publish-Subscribe-Modell sehr gut implementiert, beispielsweise die benutzerdefinierte Ereignisfunktion von Jquery.


// Publish
// jQuery: $(obj).trigger("channel", [arg1, arg2, arg3]);
$( el ).trigger( "/login", [{username:"test", userData:"test"}] );
// Dojo: dojo.publish("channel", [arg1, arg2, arg3] );
dojo.publish( "/login", [{username:"test", userData:"test"}] );
// YUI: el.publish("channel", [arg1, arg2, arg3]);
el.publish( "/login", {username:"test", userData:"test"} );
// Subscribe
// jQuery: $(obj).on( "channel", [data], fn );
$( el ).on( "/login", function( event ){...} );
// Dojo: dojo.subscribe( "channel", fn);
var handle = dojo.subscribe( "/login", function(data){..} );
// YUI: el.on("channel", handler);
el.on( "/login", function( data ){...} );
// Unsubscribe
// jQuery: $(obj).off( "channel" );
$( el ).off( "/login" );
// Dojo: dojo.unsubscribe( handle );
dojo.unsubscribe( handle );
// YUI: el.detach("channel");
el.detach( "/login" );

Einfache Implementierung


var pubsub = {};
(function(q) {
  var topics = {},
    subUid = -1;
  // Publish or broadcast events of interest
  // with a specific topic name and arguments
  // such as the data to pass along
  q.publish = function( topic, args ) {
    if ( !topics[topic] ) {
      return false;
    }
    var subscribers = topics[topic],
      len = subscribers ? subscribers.length : 0;
    while (len--) {
      subscribers[len].func( topic, args );
    }
    return this;
  };
  // Subscribe to events of interest
  // with a specific topic name and a
  // callback function, to be executed
  // when the topic/event is observed
  q.subscribe = function( topic, func ) {
    if (!topics[topic]) {
      topics[topic] = [];
    }
    var token = ( ++subUid ).toString();
    topics[topic].push({
      token: token,
      func: func
    });
    return token;
  };
  // Unsubscribe from a specific
  // topic, based on a tokenized reference
  // to the subscription
  q.unsubscribe = function( token ) {
    for ( var m in topics ) {
      if ( topics[m] ) {
        for ( var i = 0, j = topics[m].length; i < j; i++ ) {
          if ( topics[m][i].token === token) {
            topics[m].splice( i, 1 );
            return token;
          }
        }
      }
    }
    return this;
  };
}( pubsub ));

Anwendung


// Another simple message handler
// A simple message logger that logs any topics and data received through our
// subscriber
var messageLogger = function ( topics, data ) {
  console.log( "Logging: " + topics + ": " + data );
};
// Subscribers listen for topics they have subscribed to and
// invoke a callback function (e.g messageLogger) once a new
// notification is broadcast on that topic
var subscription = pubsub.subscribe( "inbox/newMessage", messageLogger );
// Publishers are in charge of publishing topics or notifications of
// interest to the application. e.g:
pubsub.publish( "inbox/newMessage", "hello world!" );
// or
pubsub.publish( "inbox/newMessage", ["test", "a", "b", "c"] );
// or
pubsub.publish( "inbox/newMessage", {
 sender: "hello@google.com",
 body: "Hey again!"
});
// We cab also unsubscribe if we no longer wish for our subscribers
// to be notified
// pubsub.unsubscribe( subscription );
// Once unsubscribed, this for example won&#39;t result in our
// messageLogger being executed as the subscriber is
// no longer listening
pubsub.publish( "inbox/newMessage", "Hello! are you still there?" );

Verwandte Empfehlungen:

Detaillierte Erläuterung des Beobachtermusters des PHP-Entwurfsmusters

Analyse von Beispielen für JavaScript-Konstruktormuster

Detaillierte Erläuterung von Beispielen für JavaScript-Fassadenmuster

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung der Beispiele für JavaScript-Beobachtermuster. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn