前端JavaScript的发布-订阅模式

发布-订阅模式又被称为观察者模式,它是定义在对象之间一对多的关系中,当一个对象发生变化,其他依赖于它的对象收到通知。在javascript的开发中,我们一般用事件模型替代发布-订阅模式。

DOM事件


    
    
  1. document.body.addEventListener( 'click', function(){
  2. alert(绑定1);
  3. }, false)};
  4. 复制代码


   
   
  1. document.body.click(); //模拟点击
  2. document.body.addEventListener('click',function(){
  3. alert(绑定2);
  4. },false)};
  5. document.body.addEventListener('click',function(){
  6. alert(绑定3);
  7. },false)};
  8. document.body.click(); //模拟点击
  9. 复制代码

我们可以增加更多订阅者,不会对发布者的代码造成影响。注意,标准浏览器下用dispatchEvent实现。

自定义事件

①确定发布者。(例如售票处)

②添加缓存列表,便于通知订阅者。(预订车票列表)

③发布消息。遍历缓存列表。依次触发里面存放的订阅者回调函数(遍历列表,逐个发送短信)。

另外,我们还可以在回调函数填入一些参数,例如车票的价格之类信息。


   
   
  1. var ticketOffice = {}; //售票处
  2. ticketOffice.clientList = []; //缓存列表,存放订阅者的回调函数
  3. ticketOffice.listen = function (fn) { //增加订阅者
  4. this.clientList.push(fn); //订阅的消息添加进缓存列表
  5. };
  6. ticketOffice.trigger = function () { //发布消息
  7. for(var i = 0, fn; fn = this.clientList[i++];){
  8. fn.apply(this, arguments); //arguments 是发布消息时带上的参数
  9. }
  10. }
  11. 下面进行简单测试:
  12. ticketOffice.listen( function(time, path){ //小刚订阅消息
  13. console.log( '时间:' + time);
  14. console.log( '路线:' + path);
  15. });
  16. ticketOffice.listen( function(time, path){ //小强订阅消息
  17. console.log( '时间:' + time);
  18. console.log( '路线:' + path);
  19. });
  20. ticketOffice.trigger( '晚上8:10', '深圳-上海');
  21. ticketOffice.trigger( '晚上8:10', '上海-深圳');
  22. 复制代码

至此,我们实现了一个最简单发布-订阅模式。不过这里存在一些问题,我们运行代码可以看到订阅者接收到了所有发布的消息。我们有必要加个key让订阅者只订阅 自己感兴趣的消息。改写后的代码如下:


   
   
  1. var ticketOffice = {}; //售票处
  2. ticketOffice.clientList = []; //缓存列表,存放订阅者的回调函数
  3. ticketOffice.listen = function (key, fn) { //增加订阅者
  4. if (!this.clientList[key]){
  5. this.clientList[key] = [];
  6. }
  7. this.clientList[key].push(fn); //订阅的消息添加进缓存列表
  8. };
  9. ticketOffice.trigger = function () { //发布消息
  10. var key = Array.prototype.shift.call(arguments), //取出消息类型
  11. fns = this.clientList[key]; //取出该消息对应的回调函数集合
  12. if (!fns || fns.length === 0) {
  13. return false;
  14. }
  15. for(var i = 0, fn; fn = fns[i++];){
  16. fn.apply(this, arguments); //arguments 是发布消息时带上的参数
  17. }
  18. }
  19. ticketOffice.listen( '上海-深圳', function(time){ //小刚订阅消息
  20. console.log( '小刚时间:' + time);
  21. });
  22. ticketOffice.listen( '深圳-上海', function(time){ //小强订阅消息
  23. console.log( '小强时间:' + time);
  24. });
  25. ticketOffice.trigger( '深圳-上海', '晚上8:00');
  26. ticketOffice.trigger( '上海-深圳', '晚上8:10');
  27. 复制代码

这样子,订阅者就可以只订阅自己感兴趣的事件了。

参考资料

《JavaScript 设计模式与开发实践》


发布了1 篇原创文章 · 获赞 0 · 访问量 109

猜你喜欢

转载自blog.csdn.net/MAYA_G/article/details/105119087
今日推荐