Heim >Web-Frontend >js-Tutorial >Ausführliche Erläuterung der Beispiele für JavaScript-Beobachtermuster
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'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 ) { $('.newMessageCounter').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'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!