представлять
Режим наблюдателя также называется Publish/Puppize. Он определяет отношения от одного ко многим, позволяя нескольким объектам наблюдателя одновременно прослушать тематический объект. Когда состояние этой темы изменяется, все объекты наблюдателя будут уведомлены, чтобы они могли автоматически обновляться.
Преимущества использования режима наблюдателя:
1. Поддерживает простую передачу вещания и автоматически уведомляет все подписанные объекты.
2. После загрузки страницы целевой объект может легко иметь динамическую корреляцию с наблюдателем, что повышает гибкость.
3. Отношение абстрактной связи между целевым объектом и наблюдателем может быть расширена и повторно используется отдельно.
Текст (версия 1)
Реализация шаблона наблюдателя в JS достигается с помощью обратных вызовов. Давайте сначала определим объект PubSub, который содержит 3 метода: подписка, отмену подписки и публикация.
Кода -копия выглядит следующим образом:
var pubsub = {};
(function (q) {
var Tepics = {}, // массив, хранящийся с помощью функции обратного вызова
subuid = -1;
// публикация метода
Q.publish = function (тема, args) {
if (! Темы [Тема]) {
вернуть ложь;
}
settimeout (function () {
var ntabrbers = темы [тема],
Len = подписчики? подписчики. Length: 0;
while (len--) {
подписчики [Len] .func (тема, Args);
}
}, 0);
вернуть истину;
};
// метод подписки
Q.SubScribe = function (тема, фанк) {
if (! Темы [Тема]) {
Темы [Тема] = [];
}
var token = (++ subuid) .toString ();
Темы [Тема] .push ({
токен: токен,
Func: Func
});
вернуть токен;
};
// метод отмены подписки
Q.UNSUBSCRIBE = function (token) {
для (var m в темах) {
if (темы [M]) {
for (var i = 0, j = темы [m] .length; i <j; i ++) {
if (темы [m] [i] .token === token) {
темы [m] .plice (i, 1);
вернуть токен;
}
}
}
}
вернуть ложь;
};
} (pubsub));
Как использовать его следующим образом:
Кода -копия выглядит следующим образом:
// Приходите, подпишитесь на один
pubsub.subscribe ('example1', function (темы, данные) {
console.log (темы + ":" + data);
});
// Уведомление о выпуске
pubsub.publish («Пример1», «Привет, мир!»);
pubsub.publish ('example1', ['test', 'a', 'b', 'c']);
pubsub.publish ('example1', [{'color': 'blue'}, {'text': 'hello'}]);
Как насчет этого? Разве это не очень хорошо использовать? Но есть проблема с этим методом, то есть нет способа отказаться от подписки. Если вы хотите отказаться от подписки, вы должны указать название отказа от подписки, поэтому давайте перейдем к другой версии:
Кода -копия выглядит следующим образом:
// назначить подписку переменной для отмены подписки
var testSubscription = pubsub.subscribe ('example1', function (темы, данные) {
console.log (темы + ":" + data);
});
// Уведомление о выпуске
pubsub.publish («Пример1», «Привет, мир!»);
pubsub.publish ('example1', ['test', 'a', 'b', 'c']);
pubsub.publish ('example1', [{'color': 'blue'}, {'text': 'hello'}]);
// unsubscription
settimeout (function () {
pubsub.unsubscribe (testsubscription);
}, 0);
// публиковать еще раз, чтобы проверить, может ли информация все еще выходить
pubsub.publish ('example1', «Привет снова! (Это потерпит неудачу)»);
Версия 2
Мы также можем использовать характеристики прототипа для реализации шаблона наблюдателя, код заключается в следующем:
Кода -копия выглядит следующим образом:
function exerver () {
this.fns = [];
}
Stemver.prototype = {
Подписаться: function (fn) {
this.fns.push (fn);
},
USOUBSCRIBE: function (fn) {
this.fns = this.fns.filter (
функция (El) {
if (el! == fn) {
вернуть Эль;
}
}
);
},
Обновление: function (o, thisObj) {
var scope = thisObj || окно;
this.fns.foreach (
функция (El) {
el.call (Scope, O);
}
);
}
};
//тест
var O = новый наблюдатель;
var f1 = function (data) {
console.log ('robbin:' + data + ', работайте быстро!');
};
var f2 = function (data) {
console.log ('randall:' + data + ', найдите его, чтобы получить дополнительную зарплату!');
};
O.SubScribe (F1);
O.SubScribe (F2);
O.Update («Том вернулся!»)
// Отписаться на F1
O.UnSubScribe (F1);
// проверить еще раз
O.Update («Том вернулся!»);
Если функция фильтра или фореата не найдена, это может быть связано с тем, что ваш браузер недостаточно новый и не поддерживает новые стандартные функции в настоящее время. Вы можете определить это самостоятельно следующим образом:
Кода -копия выглядит следующим образом:
if (! array.prototype.foreach) {
Array.prototype.foreach = function (fn, thisobj) {
var scope = thisObj || окно;
for (var i = 0, j = this.length; i <j; ++ i) {
fn.call (Scope, это [i], i, this);
}
};
}
if (! array.prototype.filter) {
Array.prototype.filter = function (fn, thisobj) {
var scope = thisObj || окно;
var a = [];
for (var i = 0, j = this.length; i <j; ++ i) {
if (! fn.call (scope, это [i], i, это)) {
продолжать;
}
A.Push (это [i]);
}
вернуть А;
};
}
Версия 3
Если вы хотите, чтобы несколько объектов имели функцию подписки Observer Publishing, мы можем определить общую функцию, а затем применить функцию функции к объекту, который требует функции наблюдателя. Код заключается в следующем:
Кода -копия выглядит следующим образом:
// Универсальный код
var exerver = {
//подписка
addSubScriber: function (обратный вызов) {
this.subscribers [this.subscribers.length] = обратный вызов;
},
// unsubscription
RemovesubScriber: function (обратный вызов) {
for (var i = 0; i <this.subscribers.length; i ++) {
if (this.subscribers [i] === Callback) {
удалить (this.subscribers [i]);
}
}
},
//выпускать
Publish: function (что) {
for (var i = 0; i <this.subscribers.length; i ++) {
if (typeof this.subscribers [i] === 'function') {
this.subscribers [i] (что);
}
}
},
// Сделать объект o иметь функцию наблюдателя
сделать: function (o) {
для (var i в этом) {
o [i] = это [i];
O.SubScribers = [];
}
}
};
Затем подпишитесь на 2 объекта Blogger и пользователя, используйте метод Observer.make, чтобы эти два объекта выполняли функции наблюдателя, код заключается в следующем:
Кода -копия выглядит следующим образом:
var blogger = {
Рекомендую: function (id) {
var msg = 'Dudu Рекомендуемое сообщение:' + id;
this.publish (msg);
}
};
var user = {
Голосовать: function (id) {
var msg = 'кто -то проголосовал! id =' + id;
this.publish (msg);
}
};
stemver.make (блогер);
stemver.make (пользователь);
Метод использования относительно прост. Подпишитесь на различные функции обратного вызова, чтобы вы могли зарегистрироваться в различных объектах наблюдателя (или несколько объектов наблюдателя могут быть зарегистрированы одновременно):
Кода -копия выглядит следующим образом:
var tom = {
Читать: function (что) {
console.log ('Том увидел следующее сообщение:' + Что)
}
};
var mm = {
show: function (что) {
console.log ('мм увидел следующее сообщение:' + Что)
}
};
// Подписаться
blogger.addsubscriber (Tom.read);
blogger.addsubscriber (Mm.show);
blogger.recommend (123); // позвонить опубликовать
// unsubscription
blogger.removesubscriber (mm.show);
blogger.recommend (456); // позвонить опубликовать
// подписаться на другой объект
user.addsubscriber (mm.show);
user.vote (789); // позвонить опубликовать
jQuery версия
Согласно функции включения/выключения, добавленной в JQUERY версии 1.7, мы также можем определить наблюдатель версии jQuery:
Кода -копия выглядит следующим образом:
(function ($) {
var O = $ ({});
$ .subscribe = function () {
o.on.apply (o, аргументы);
};
$ .unsubscribe = function () {
o.off.apply (o, аргументы);
};
$ .publish = function () {
o.trigger.apply (o, аргументы);
};
} (jQuery));
Призыв метод проще, чем вышеупомянутые три версии:
Кода -копия выглядит следующим образом:
// Функция обратного вызова
Ручке функции (E, A, B, C) {
// `e` - объект события, не требуется внимания
console.log (a + b + c);
};
//подписка
$ .subscribe ("/some/topic", ручка);
//выпускать
$ .publish ("/some/topic", ["a", "b", "c"]); // Вывод ABC
$ .unsubscribe ("/some/topic", handle); // Отписаться
//подписка
$ .subscribe ("/some/topic", function (e, a, b, c) {
console.log (a + b + c);
});
$ .publish ("/some/topic", ["a", "b", "c"]); // Вывод ABC
// Отказ от подписки (USOUBSCRIBE использует имя/некоторое/тема, а не функция обратного вызова, которая отличается от примера версии 1
$ .UnSubScribe ("/немного/тема");
Можно видеть, что его подписка и отказа от подписки используют имена строк, а не имена функций обратного вызова, поэтому даже если входящая анонимная функция передается, мы можем отписаться.
Суммировать
Использование наблюдателей: когда объект меняется, чтобы изменить другие объекты одновременно, и он не знает, сколько объектов необходимо изменить, он должен рассмотреть возможность использования режима наблюдателя.
В целом, то, что делает шаблон наблюдателя, является департаментом, заставляя обе стороны муфты полагаться на абстракцию, а не конкретную. Это делает возможным, что изменения друг друга не будут влиять на изменения на другой стороне.