Введение в модель подписки-публикации
Модель "публикация-подписка", определяющая отношение "один ко многим", позволяет нескольким объектам-наблюдателям отслеживать объект темы. При изменении объекта темы все зависимые объекты будут уведомлены.
Мы часто сталкиваемся с такой ситуацией в нашей жизни.Когда мы используем новостные приложения для просмотра новостей, всем нравятся разные типы новостей.Например, мне нравится NBA, но мы не можем постоянно быть в наших мобильных телефонах 24 часа в сутки.Однажды обновившись, мы перейдем к новостному каналу, чтобы выбрать колонку НБА для сбора, и когда «Уорриорз» или «Лейкерс» получат последние новости, мы получим уведомление о просмотре.
Конечно, приведенный выше сценарий является типичной моделью публикации и подписки. Колонка НБА в приложении принадлежит издателю, а мечта таких любителей баскетбола, как я, принадлежит подписчику. Когда появятся последние новости, они будут опубликованы. мы. .
реальная функция
1. Во многих местах jquery есть следы публикации и подписки, например, методы, инкапсулированные в событиях on, и триггеры в событиях.
2. Затем добавить к издателю список кеша для хранения функций обратного вызова для уведомления подписчиков (например, столбец NBA собирается нашими фанатами выше, что эквивалентно внедрению функции уведомления в издатель);
3, конец — это сообщение об освобождении, издатель просматривает список кеша и запускает функцию подписчика.
В спешке наблюдая, возьмите небольшую скамейку и взгляните на эту простую модель публикации-подписки:
let NBAcol={};//自定义一个NBA专栏对象
NBAcol.list=[];// 这里放一个列表用来缓存订阅者的回调函数
NBAcol.on=function(fun){
this.list.push(fun); //把fn先存到列表中
};
//发布事件
NBAcol.emit=function(){
this.list.forEach(cb => {
cb.apply(this, arguments);
});// 当发布的时候再把列表里存的函数依次执行
};
//小明的订阅NBA专栏
NBAcol.on(function(team){
console.log("我订阅的球队是:"+team)
})
//小李的订阅NBA专栏
NBAcol.on(function(team){
console.log("我订阅的球队是:"+team)
})
NBAcol.emit('湖人');
NBAcol.emit('勇士');
/*
我订阅的球队是:湖人;
我订阅的球队是:湖人;
我订阅的球队是:勇士;
我订阅的球队是:勇士;
*/
Вышеприведенное реализует простую модель подписки и публикации, но, судя по результатам печати, это немного смущает, потому что на самом деле Сяо Мин хочет подписаться только на «Лейкерс», а Сяо Ли хочет подписаться на «Уорриорз». Но колонки все к ним подталкивают, что явно не разумно. Причина этого в том, что функции в списке функций подписки выполняются последовательно при выполнении метода on. Итак, нам нужно изменить код, мы можем сначала добавить ключ, чтобы подписчики подписывались только на те сообщения, которые им интересны.
let NBAcol={};//自定义一个NBA专栏对象
NBAcol.list={};// 这里放一个列表用来缓存订阅者的回调函数
NBAcol.on=function(key,fun){
// 如果还没有订阅过此类消息,给该类消息创建一个缓存列表
if(!this.list[key]){
this.list[key]=[];
}
this.list[key].push(fun); //把fn先存到列表中
};
//发布事件
NBAcol.emit=function(){
let key=Array.prototype.shift.call(arguments);// 取出消息类型名称
let funs=this.list[key];//匹配对应的回调函数的结合
if(!funs||funs.length===0){//如果没有订阅过消息,则return;
return;
};
funs.forEach(fun => {
fun.apply(this, arguments);
});// 当发布的时候再把列表里存的函数依次执行
};
//小明的订阅NBA专栏
NBAcol.on('xiaomin',function(team){
console.log("我订阅的球队是:"+team)
})
//小李的订阅NBA专栏
NBAcol.on('xiaoli',function(team){
console.log("我订阅的球队是:"+team)
})
NBAcol.emit('xiaomin','湖人');
NBAcol.emit('xiaoli','勇士');
/*
我订阅的球队是:湖人;
我订阅的球队是:勇士;
*/
Вот и все, основная функция этой подписной публикации была отражена.
Как отписаться от мероприятия
Например, вышеупомянутый Liezi, если мы подписываемся на множество вещей, мы хотим отменить подписку, когда она нам не нравится, что нам делать? См. следующий код:
NBAcol.remove=function(key, fun) {
// 这回我们加入了取消订阅的方法
let funs = this.list[key];
// 如果缓存列表中没有函数,返回false
if (!funs) return false;
// 如果没有传对应函数的话
// 就会将key值对应缓存列表中的函数都清空掉
if (!fun) {
funs && (funs.length = 0);
} else {
// 遍历缓存列表,看看传入的fun与哪个函数相同
// 如果相同就直接从缓存列表中删掉即可
funs.forEach((cb, i) => {
if (cb === fun) {
funs.splice(i, 1);
}
});
}
}
// 取消dog方法的订阅
NBAcol.remove('xiaoli',function(team){
console.log("我订阅的球队是:"+team)
});
Таким образом, подписку можно отменить, но в фактическом открытом исходном коде инкапсуляция гораздо сложнее, чем это, например, количество подписок, инкапсуляция многомодульных подписок и т. д., поэтому здесь мы должны подробно в самом бизнес-модуле.
Публикация недостатков режимов подписки:
Разумеется, одна из вещей двусторонняя, и в режиме подписки доступны следующие выпуски:
1, создание абонента должна потреблять определенное количество времени и памяти.
2. Хотя это может ослабить связь между объектами, при чрезмерном использовании это затруднит понимание и сопровождение кода.