einführen
Der Observer -Modus heißt auch Publish/Abonnieren. Es definiert eine Eins-zu-Viele-Beziehung, sodass mehrere Observer-Objekte gleichzeitig auf ein Themenobjekt hören können. Wenn sich der Status dieses Themenobjekts ändert, werden alle Beobachterobjekte benachrichtigt, damit sie sich automatisch selbst aktualisieren können.
Vorteile der Verwendung des Beobachtermodus:
1. unterstützt einfache Broadcast -Kommunikation und benachrichtigt automatisch alle abonnierten Objekte.
2. Nachdem die Seite geladen wurde, kann das Zielobjekt leicht eine dynamische Korrelation mit dem Beobachter aufweisen, was die Flexibilität erhöht.
3. Die abstrakte Kopplungsbeziehung zwischen dem Zielobjekt und dem Beobachter kann separat erweitert und wiederverwendet werden.
Text (Version 1)
Die Implementierung des Beobachtermusters in JS wird durch Rückrufe erreicht. Definieren wir zunächst ein PubSub -Objekt, das 3 Methoden enthält: Abonnement, Abmelden und Veröffentlichung.
Die Codekopie lautet wie folgt:
var pubSub = {};
(Funktion (q) {
var topics = {}, // Array, das von der Rückruffunktion gespeichert ist
subuid = -1;
// Methode veröffentlichen
Q.Publish = Funktion (Thema, args) {
if (! Themen [Thema]) {
false zurückgeben;
}
setTimeout (function () {
var subskers = themen [thema],
Len = Abonnenten? Abonnenten.Length: 0;
während (len--) {
Abonnenten [len] .func (Thema, Argumente);
}
}, 0);
zurückkehren;
};
// Methode abonnieren
Q.Subscribe = Funktion (Thema, func) {
if (! Themen [Thema]) {
Themen [Thema] = [];
}
var token = (++ subuid) .ToString ();
Themen [Thema] .push ({{
Token: Token,
Func: Func
});
Rückgabe -Token;
};
// METORSUBSIBRIKT -METHODE
q.unsubscribe = function (token) {
für (var m in themen) {
if (themen [m]) {
für (var i = 0, j = themen [m] .Length; i <j; i ++) {
if (themen [m] [i] .Token === Token) {
Themen [m] .SPLICE (i, 1);
Rückgabe -Token;
}
}
}
}
false zurückgeben;
};
} (PubSub));
Wie man es benutzt, ist wie folgt:
Die Codekopie lautet wie folgt:
// Komm, abonniere einen
PubSub.Subscribe ('Beispiel1', Funktion (Themen, Daten) {
console.log (Themen + ":" + Daten);
});
// Bekanntmachung über die Veröffentlichung
PubSub.Publish ('Beispiel1', 'Hallo Welt!');
PubSub.Publish ('Beispiel1', ['Test', 'A', 'B', 'C']);
PubSub.Publish ('example1', [{'color': 'blau'}, {'text': 'hello'}]);
Wie wäre es damit? Ist es nicht sehr gut zu verwenden? Es gibt jedoch ein Problem mit dieser Methode, dh es gibt keine Möglichkeit, sich abzuschreiben. Wenn Sie sich abmelden möchten, müssen Sie den Namen des Abbestellens angeben. Gehen wir also zu einer anderen Version:
Die Codekopie lautet wie folgt:
// Zuwenden Sie das Abonnement einer Variablen ab, um abzuschreiben
var testsubScription = PubSub.SubScribe ('Beispiel1', Funktion (Themen, Daten) {
console.log (Themen + ":" + Daten);
});
// Bekanntmachung über die Veröffentlichung
PubSub.Publish ('Beispiel1', 'Hallo Welt!');
PubSub.Publish ('Beispiel1', ['Test', 'A', 'B', 'C']);
PubSub.Publish ('example1', [{'color': 'blau'}, {'text': 'hello'}]);
// unssubscription
setTimeout (function () {
PubSub.UnSubscribe (TestsubScription);
}, 0);
// erneut veröffentlichen, um zu überprüfen, ob die Informationen weiterhin ausgegeben werden können
PubSub.Publish ('Beispiel1', 'Hallo nochmal! (Dies wird scheitern)');
Version 2
Wir können auch die Eigenschaften des Prototyps verwenden, um ein Beobachtermuster zu implementieren. Der Code lautet wie folgt:
Die Codekopie lautet wie folgt:
Funktion Observer () {
this.fns = [];
}
Observer.prototype = {
Abonnieren: Funktion (fn) {
this.fns.push (fn);
},
Abbestellen: Funktion (fn) {
this.fns = this.fns.filter (
Funktion (el) {
if (el! == fn) {
return el;
}
}
);
},
UPDATE: Funktion (o, thisoBj) {
var scope = thisobj || Fenster;
this.fns.foreach (
Funktion (el) {
El.Call (Scope, O);
}
);
}
};
//prüfen
var o = neuer Beobachter;
var f1 = Funktion (Daten) {
console.log ('Robbin:' + data + ', schnell arbeiten!');
};
var f2 = Funktion (Daten) {
console.log ('randall:' + data + ', finde ihn, um ein zusätzliches Gehalt zu bekommen!');
};
O.Subscribe (F1);
O.Subscribe (F2);
O.Update ("Tom ist zurück!")
// Abzünden Sie F1
O.unsubscribe (F1);
// erneut überprüfen
O.Update ("Tom ist zurück!");
Wenn der Filter oder die Funktion für die Liege nicht gefunden wird, kann dies daran liegen, dass Ihr Browser vorerst nicht neu genug ist und keine neuen Standardfunktionen unterstützt. Sie können es selbst auf folgende Weise definieren:
Die Codekopie lautet wie folgt:
if (! array.prototype.foreach) {
Array.Prototype.foreach = Funktion (fn, thisobj) {
var scope = thisobj || Fenster;
für (var i = 0, j = this.Length; i <j; ++ i) {
fn.call (Scope, this [i], i, this);
}
};
}
if (! array.prototype.filter) {
Array.prototype.filter = function (fn, thisobj) {
var scope = thisobj || Fenster;
var a = [];
für (var i = 0, j = this.Length; i <j; ++ i) {
if (! fn.call (scope, this [i], i, this) {
weitermachen;
}
a.push (this [i]);
}
Rückkehr a;
};
}
Version 3
Wenn Sie möchten, dass mehrere Objekte die Funktion des Beobachterverlagungsabonnements haben, können wir eine gemeinsame Funktion definieren und dann die Funktion der Funktion auf das Objekt anwenden, für das die Beobachterfunktion erforderlich ist. Der Code ist wie folgt:
Die Codekopie lautet wie folgt:
// Universal Code
var observer = {
//Abonnement
AddSubscriber: Funktion (Callback) {
this.SubSchers [this.SubSchers.Length] = Callback;
},
// unssubscription
REMOVESUBSCRIBER: Funktion (Rückruf) {
für (var i = 0; i <this.SubScriptions.length; i ++) {
if (this.SubSchers [i] === Callback) {
löschen (this.SubSchers [i]);
}
}
},
//freigeben
veröffentlichen: function (was) {
für (var i = 0; i <this.SubScriptions.length; i ++) {
if (typeof this.SubScribieren [i] === 'Funktion') {
this.SubSchers [i] (was);
}
}
},
// Objekt o Beobachterfunktion haben
make: function (o) {
für (var i in diesem) {
o [i] = this [i];
O.SubScrippen = [];
}
}
};
Abonnieren Sie dann 2 Objekte -Blogger und Benutzer, verwenden Sie die Beobachter.Make -Methode, um diese beiden Objekte Beobachterfunktionen zu erstellen. Der Code lautet wie folgt:
Die Codekopie lautet wie folgt:
var blogger = {
Empfehlen: function (id) {
var msg = 'Dudu empfohlene Post:' + id;
this.publish (msg);
}
};
var user = {
Abstimmung: Funktion (id) {
var msg = 'Jemand hat abgestimmt! ID =' + id;
this.publish (msg);
}
};
Observer.Make (Blogger);
Observer.Make (Benutzer);
Die Verwendungsmethode ist relativ einfach. Abonnieren Sie verschiedene Rückruffunktionen, damit Sie sich bei verschiedenen Observer -Objekten registrieren können (oder mehrere Observer -Objekte können gleichzeitig registriert werden):
Die Codekopie lautet wie folgt:
var tom = {
Lesen Sie: Funktion (was) {
console.log ('Tom sah die folgende Nachricht:' + was)
}
};
var mm = {
Show: function (was) {
console.log ('mm sah die folgende Nachricht:' + was)
}
};
// Abonnieren
blogger.addsubscriber (tom.read);
blogger.addsubscriber (mm.show);
Blogger.Recommend (123); // Rufen Sie die Veröffentlichung an
// unssubscription
blogger.removesubscriber (mm.show);
Blogger.Recommend (456); // Rufen Sie die Veröffentlichung an
// Abonnieren Sie ein anderes Objekt
user.addsubscriber (mm.show);
user.vote (789); // Rufen Sie die Veröffentlichung an
JQuery -Version
Gemäß der in JQuery Version 1.7 hinzugefügten Ein/Aus -Funktion können wir auch den Beobachter der Jquery -Version definieren:
Die Codekopie lautet wie folgt:
(Funktion ($) {
var o = $ ({});
$ .subscribe = function () {
o.on.apply (o, Argumente);
};
$ .unsubscribe = function () {
O.off.Apply (o, Argumente);
};
$ .publish = function () {
o.trigger.apply (o, Argumente);
};
} (jQuery));
Die Aufrufmethode ist einfacher als die oben genannten drei Versionen:
Die Codekopie lautet wie folgt:
// Rückruffunktion
Funktion Handle (e, a, b, c) {
// `e` ist ein Ereignisobjekt, es ist keine Aufmerksamkeit erforderlich
console.log (a + b + c);
};
//Abonnement
$ .Subscribe ("/einige/topic", Handle);
//freigeben
$ .publish ("/einige/themen", ["a", "b", "c"]); // Ausgabe ABC
$ .unSubscribe ("/einige/topic", Handle); // Abbestellen
//Abonnement
$ .Subscribe ("/einige/themen", Funktion (e, a, b, c) {
console.log (a + b + c);
});
$ .publish ("/einige/themen", ["a", "b", "c"]); // Ausgabe ABC
// Absubscribe (Absubscribe verwendet den Namen/einige/Themename, nicht die Rückruffunktion, die sich vom Beispiel von Version 1 unterscheidet
$ .unSubscribe ("/einige/topic");
Es ist zu sehen, dass sein Abonnement und Abonnement und Abmeldungsnamen und keine Rückruffunktionsnamen verwendet werden. Selbst wenn die eingehende anonyme Funktion übergeben wird, können wir uns abmelden.
Zusammenfassen
Die Verwendung von Beobachtern ist: Wenn sich ein Objekt ändert, um andere Objekte gleichzeitig zu ändern und nicht weiß, wie viele Objekte geändert werden müssen, sollte es in Betracht ziehen, den Observer -Modus zu verwenden.
Insgesamt ist das Beobachtermuster entkoppelt, wodurch beide Seiten der Kopplung eher auf Abstraktion als auf Beton angewiesen sind. Dies ermöglicht es, dass sich die Änderungen der anderen nicht auf die Änderungen auf der anderen Seite auswirken.