document.body.addEventListener('click',function(){
alert(绑定1);
},false)};
复制代码
document.body.click(); //模拟点击
document.body.addEventListener('click',function(){
alert(绑定2);
},false)};
document.body.addEventListener('click',function(){
alert(绑定3);
},false)};
document.body.click(); //模拟点击
复制代码
咱们能够增长更多订阅者,不会对发布者的代码形成影响。注意,标准浏览器下用dispatchEvent实现。javascript
①肯定发布者。(例如售票处)java
②添加缓存列表,便于通知订阅者。(预订车票列表)设计模式
③发布消息。遍历缓存列表。依次触发里面存放的订阅者回调函数(遍历列表,逐个发送短信)。浏览器
另外,咱们还能够在回调函数填入一些参数,例如车票的价格之类信息。缓存
var ticketOffice = {}; //售票处
ticketOffice.clientList = []; //缓存列表,存放订阅者的回调函数
ticketOffice.listen = function (fn) { //增长订阅者
this.clientList.push(fn); //订阅的消息添加进缓存列表
};
ticketOffice.trigger = function () { //发布消息
for(var i = 0, fn; fn = this.clientList[i++];){
fn.apply(this, arguments); //arguments 是发布消息时带上的参数
}
}
下面进行简单测试:
ticketOffice.listen(function(time, path){ //小刚订阅消息
console.log('时间:' + time);
console.log('路线:' + path);
});
ticketOffice.listen(function(time, path){ //小强订阅消息
console.log('时间:' + time);
console.log('路线:' + path);
});
ticketOffice.trigger('晚上8:10','深圳-上海');
ticketOffice.trigger('晚上8:10','上海-深圳');
复制代码
至此,咱们实现了一个最简单发布-订阅模式。不过这里存在一些问题,咱们运行代码能够看到订阅者接收到了全部发布的消息。咱们有必要加个key让订阅者只订阅 本身感兴趣的消息。改写后的代码以下:
bash
var ticketOffice = {}; //售票处
ticketOffice.clientList = []; //缓存列表,存放订阅者的回调函数
ticketOffice.listen = function (key, fn) { //增长订阅者
if (!this.clientList[key]){
this.clientList[key] = [];
}
this.clientList[key].push(fn); //订阅的消息添加进缓存列表
};
ticketOffice.trigger = function () { //发布消息
var key = Array.prototype.shift.call(arguments), //取出消息类型
fns = this.clientList[key]; //取出该消息对应的回调函数集合
if (!fns || fns.length === 0) {
return false;
}
for(var i = 0, fn; fn = fns[i++];){
fn.apply(this, arguments); //arguments 是发布消息时带上的参数
}
}
ticketOffice.listen('上海-深圳', function(time){ //小刚订阅消息
console.log('小刚时间:' + time);
});
ticketOffice.listen('深圳-上海', function(time){ //小强订阅消息
console.log('小强时间:' + time);
});
ticketOffice.trigger('深圳-上海', '晚上8:00');
ticketOffice.trigger('上海-深圳', '晚上8:10');
复制代码
这样子,订阅者就能够只订阅本身感兴趣的事件了。app
《JavaScript 设计模式与开发实践》函数