1. // 观察者模式/发布者订阅者模式
    2. // 这个算是js中常见的设计模式了 react中的state数据存储和使用 就是这种模式
    3. // 还有监听事件 监听某个事件 当事件发生时 执行回调函数
    4. // 在生活中 好莱坞有句台词可以来形容这个模式 --不要给我打电话 我会给你打电话 、
    5. // 现在手机app的推送消息也可以理解为这种模式
    6. // 这种模式实现也很简单
    7. // 发布者维护一个数组 用以保存订阅者对象的回调函数
    8. // 发布者有一个注册订阅者和取消订阅的方法 最后再有一个发布消息的方法即可
    9. // 代码实现
    10. // 发布者维护一个对象 对象的key是事件名称 value是{}, 每个订阅者的回调函数
    11. function EventEmitter (){
    12. this.events = {};
    13. }
    14. // 发布者的订阅方法
    15. EventEmitter.prototype.subscribe = function(event, key, callBack){
    16. if(!this.events[event]){
    17. // 还没有人订阅过这个事件 初始化存放回调函数的数据
    18. this.events[event] = {};
    19. }
    20. // 添加回调函数
    21. this.events[event][key] = callBack;
    22. }
    23. // 取消订阅方法
    24. EventEmitter.prototype.unSubscribe = function(event, key){
    25. if(this.events[event] && this.events[event][key]){
    26. delete this.events[event][key];
    27. }
    28. }
    29. // 发布者发布事件的方法
    30. EventEmitter.prototype.dispatch = function(event, data){
    31. // 没人订阅你发个毛线
    32. if(!this.events) return;
    33. for(var key in this.events[event]){
    34. // console.log("-------------");
    35. // console.log(key);
    36. // console.log(this.events[event][key]);
    37. this.events[event][key](data);
    38. }
    39. }
    40. // 上面就是一个简单的发布者订阅者模式
    41. // 下面举例使用例子
    42. // 我们去餐馆吃饭 坐在位子上跟服务员点菜
    43. // 服务员在单子上写下几号座点了什么菜
    44. // 做好了菜服务员会端菜上来 并在菜单上划掉上的菜
    45. // 这里服务员就是发布者 顾客就是订阅者
    46. // 创建个服务员
    47. var waiter = new EventEmitter();
    48. // 一号桌点了一份宫保鸡丁。。
    49. waiter.subscribe("宫保鸡丁", "1号桌", function(data){
    50. console.log("1号桌的" + data + "上完了");
    51. // 在菜单上划掉这一项
    52. waiter.unSubscribe("宫保鸡丁", "1号桌");
    53. });
    54. // 二号桌点了猪肉炖粉条
    55. waiter.subscribe("猪肉炖粉条", "2号桌", function(data){
    56. console.log("2号桌的" + data + "上完了");
    57. waiter.unSubscribe("猪肉炖粉条", "2号桌");
    58. });
    59. // 上菜了
    60. console.log("宫保鸡丁上菜了");
    61. waiter.dispatch("宫保鸡丁" , "大盘宫保鸡丁");
    62. // 二号桌又点了宫保鸡丁
    63. waiter.subscribe("宫保鸡丁", "2号桌", function(data){
    64. console.log("2号桌的" + data + "上完了");
    65. waiter.unSubscribe("宫保鸡丁", "2号桌");
    66. });
    67. // 猪肉炖粉条上了
    68. console.log("猪肉炖粉条上菜了");
    69. waiter.dispatch("猪肉炖粉条" , "猪肉炖粉条");
    70. // 宫保鸡丁上菜
    71. console.log("宫保鸡丁上菜了");
    72. waiter.dispatch("宫保鸡丁" , "小盘宫保鸡丁");
    73. // jq中也为发布者订阅者模式提供了接口
    74. // $().on $().off
    75. function eventWatcher () {
    76. console.log("事件触发了");
    77. }
    78. $(document).on("divEvent", eventWatcher);
    79. $(document).trigger("divEvent");
    80. $(document).off("divEvent");
    81. $(document).trigger("divEvent");