标签:fir this 之间 参考 存在 调用 联系 第一个 说明
发布-订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。
订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Event Channel),当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
2 发布订阅模式的图解以及与观察者模式之间的差异和类似之处:
3 实现发布订阅模式的 相关思路:
eg1:简单一点的demo:
// 定义一个对象作为调度中心,或者一个类。
let eventEmitter = {};
// 缓存列表,存放 event 及 fn
eventEmitter.list = {};
// 订阅
eventEmitter.on = function (event, fn) {
let _this = this;
// 如果对象中没有对应的 event 值,也就是说明没有订阅过,就给 event 创建个缓存列表
// 如有对象中有相应的 event 值,把 fn 添加到对应 event 的缓存列表里
(_this.list[event] || (_this.list[event] = [])).push(fn);
return _this;
};
// 发布
eventEmitter.emit = function () {
let _this = this;
// 第一个参数是对应的 event 值,直接用数组的 shift 方法取出
let event = [].shift.call(arguments), // 删除并拿到arguments
的第一项 详细参考:https://blog.csdn.net/u013946061/article/details/108269650博客。
fns = [..._this.list[event]];
// 如果缓存列表里没有 fn 就返回 false
if (!fns || fns.length === 0) {
return false;
}
// 遍历 event 值对应的缓存列表,依次执行 fn
fns.forEach(fn => {
fn.apply(_this, arguments);
});
return _this;
};
function user1 (content) {
console.log(‘用户1订阅了:‘, content);
};
function user2 (content) {
console.log(‘用户2订阅了:‘, content);
};
// 订阅
eventEmitter.on(‘article‘, user1);
eventEmitter.on(‘article‘, user2);
// 发布
eventEmitter.emit(‘article‘, ‘Javascript 发布-订阅模式‘);
/*
用户1订阅了: Javascript 发布-订阅模式
用户2订阅了: Javascript 发布-订阅模式
*/e
eg2: 实现一次订阅的once方法和取消订阅的off方法:
let eventEmitter = { // 缓存列表 list: {}, // 订阅 on (event, fn) { let _this = this; // 如果对象中没有对应的 event 值,也就是说明没有订阅过,就给 event 创建个缓存列表 // 如有对象中有相应的 event 值,把 fn 添加到对应 event 的缓存列表里 (_this.list[event] || (_this.list[event] = [])).push(fn); return _this; }, // 监听一次 并且只执行一次 之后取消订阅 once (event, fn) { // 先绑定,调用后删除 let _this = this; function on () { _this.off(event, on); //取消订阅 fn.apply(_this, arguments); // 执行fn函数 } on.fn = fn; _this.on(event, on); return _this; }, // 取消订阅 off (event, fn) { let _this = this; let fns = _this.list[event]; // 如果缓存列表中没有相应的 fn,返回false if (!fns) return false; if (!fn) { // 如果没有传 fn 的话,就会将 event 值对应缓存列表中的 fn 都清空 fns && (fns.length = 0); } else { // 若有 fn,遍历缓存列表,看看传入的 fn 与哪个函数相同,如果相同就直接从缓存列表中删掉即可 let cb; for (let i = 0, cbLen = fns.length; i < cbLen; i++) { cb = fns[i]; if (cb === fn || cb.fn === fn) { fns.splice(i, 1); break } } } return _this; }, // 发布 emit () { let _this = this; // 第一个参数是对应的 event 值,直接用数组的 shift 方法取出 let event = [].shift.call(arguments), fns = [..._this.list[event]]; // 如果缓存列表里没有 fn 就返回 false if (!fns || fns.length === 0) { return false; } // 遍历 event 值对应的缓存列表,依次执行 fn fns.forEach(fn => { fn.apply(_this, arguments); }); return _this; } }; function user1 (content) { console.log(‘用户1订阅了:‘, content); } function user2 (content) { console.log(‘用户2订阅了:‘, content); } function user3 (content) { console.log(‘用户3订阅了:‘, content); } function user4 (content) { console.log(‘用户4订阅了:‘, content); } // 订阅 eventEmitter.on(‘article1‘, user1); eventEmitter.on(‘article1‘, user2); eventEmitter.on(‘article1‘, user3); // 取消user2方法的订阅 eventEmitter.off(‘article1‘, user2); eventEmitter.once(‘article2‘, user4) // 发布 eventEmitter.emit(‘article1‘, ‘Javascript 发布-订阅模式‘); eventEmitter.emit(‘article1‘, ‘Javascript 发布-订阅模式‘); eventEmitter.emit(‘article2‘, ‘Javascript 观察者模式‘); eventEmitter.emit(‘article2‘, ‘Javascript 观察者模式‘); // eventEmitter.on(‘article1‘, user3).emit(‘article1‘, ‘test111‘); /* 用户1订阅了: Javascript 发布-订阅模式 用户3订阅了: Javascript 发布-订阅模式 用户1订阅了: Javascript 发布-订阅模式 用户3订阅了: Javascript 发布-订阅模式 用户4订阅了: Javascript 观察者模式 */
1 优点:
2 不足之处:
观察者模式和发布订阅模式之间的区别和异同:
观察者模式
:观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被激活的时候,会触发(Fire Event)观察者里的事件。
发布订阅模式
:订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Event Channel),当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
差异:
标签:fir this 之间 参考 存在 调用 联系 第一个 说明
原文地址:https://www.cnblogs.com/taue997/p/14903550.html