1. var publisher = {
  2.  
  3. // 订阅者数组
  4. subscribers : {
  5. "any" : []
  6. },
  7.  
  8. // 增加订阅者
  9. on : function(type, fn, context){
  10. var subscribers = this.subscribers;
  11. type = type || "any";
  12. context = context || this;
  13. fn = typeof fn === "function" ? fn : context[fn];
  14. if(!subscribers[type]){
  15. subscribers[type] = [];
  16. }
  17. subscribers[type].push({"fn" : fn, "context" : context});
  18. },
  19.  
  20. // 移除订阅者
  21. off : function(type, fn, context){
  22. this.visit("unPublish", type, fn, context)
  23. },
  24.  
  25. // 通知
  26. fire : function(type, arg){
  27. this.visit("publish", type, arg);
  28. },
  29.  
  30. // 访问订阅者数组
  31. visit : function(action, type, arg, context){
  32. var subscribers, i, len;
  33. type = type || "any";
  34. subscribers = this.subscribers[type];
  35. len = subscribers.length || 0;
  36.  
  37. switch(action){
  38. case "publish" :
  39. for(i = 0; i < len; i++){
  40. subscribers[i].fn.call(subscribers[i].context, arg);
  41. }
  42. break;
  43. case "unPublish":
  44. for(i = 0; i < len; i++){
  45. if(subscribers[i].fn === arg && subscribers[i].context === context){
  46. subscribers.splice(i, 1);
  47. }
  48. }
  49. break;
  50. }
  51. }
  52. };
  53.  
  54. function makePublisher(o){
  55. o.subscribers = {"any" : []};
  56. for(var p in publisher ){
  57. if(publisher.hasOwnProperty(p) && typeof publisher[p] === "function"){
  58. o[p] = publisher[p];
  59. }
  60. }
  61. return o;
  62. }
  63.  
  64. // 发布者Play
  65. // 发布两个事件:1、有玩家加入 2、玩家开始玩
  66. function Player(name, key){
  67. this.point = 0;
  68. this.name = name;
  69. this.key = key;
  70. this.fire("add", this);
  71. }
  72.  
  73. Player.prototype.play = function(){
  74. this.point += 1;
  75. this.fire("play", this);
  76. };
  77.  
  78. // 观察者/订阅者 game,观察2个事件:1、有玩家加入 2、玩家开始玩
  79. // 同时作为发布者game,通知积分榜更新
  80. var game = {
  81. // 存储对象和按键key的关系
  82. keys : {},
  83. // 订阅
  84. addPlayer : function(player){
  85. this.keys[player.key] = player;
  86. },
  87.  
  88. // 通知订阅者scoreboard更新
  89. handlyPlay : function(){
  90. var score = {}, keys = this.keys, p;
  91. for(p in keys){
  92. if(keys.hasOwnProperty(p)){
  93. score[keys[p].name] = keys[p].point;
  94. }
  95. }
  96. this.fire("update", score);
  97. },
  98.  
  99. // 封装keypress事件
  100. keydown : function(e){
  101. var which, code;
  102. e = e || event;
  103. which = e.which || e.keyCode;
  104. code = String.fromCharCode(which);
  105. if(this.keys[code]){
  106. this.keys[code].play();
  107. }
  108. }
  109. };
  110.  
  111. // 积分榜
  112. var scoreboard = {
  113. dom : document.getElementById("score_board"),
  114.  
  115. // 更新积分榜 参数格式 {playname1 : point, playname2 : point }
  116. update : function(score){
  117. var p, html = "";
  118. for(p in score){
  119. if(score.hasOwnProperty(p)){
  120. html += p + "获得了" + score[p] + "<br/>";
  121. }
  122. }
  123. this.dom.innerHTML = html;
  124. }
  125. };
  126.  
  127. // Player作为发布者,因其需要通知订阅者game新增玩家以及玩家积分变化
  128. // game对Player而言是订阅者,因其需要订阅Player的特定活动add(新增玩家)和play(玩家积分发生变化)
  129. // game对scoreboard而言是发布者,因其在观察到Player的play事件之后需要通知scoreboard更新积分
  130. makePublisher(Player.prototype);
  131. makePublisher(game);
  132.  
  133. Player.prototype.on("add", game.addPlayer, game);
  134. Player.prototype.on("play", game.handlyPlay, game);
  135. game.on("update", scoreboard.update, scoreboard);
  136.  
  137. //excute
  138. while(true){
  139. var name = prompt("say your name, man"), key;
  140. if(name && name !== "null"){
  141. while(true){
  142. key = prompt("what is your key");
  143. if(key && key !== "null"){
  144. break;
  145. }
  146. alert("亲,还是指定个key吧,不然你没办法玩的,相信我");
  147. }
  148. new Player(name, key);
  149. }
  150. else {
  151. break;
  152. }
  153. }
  154.  
  155. document.onkeydown = function(e){
  156. game.keydown.call(game, e);
  157. };

Javascript模式(二) 发布者/订阅者模式的更多相关文章

  1. JavaScript 设计模式: 发布者-订阅者模式

    JavaScript 设计模式: 发布者-订阅者模式 发布者-订阅者模式 https://github.com/Kelichao/javascript.basics/issues/22 https:/ ...

  2. vue双向绑定(数据劫持+发布者-订阅者模式)

    参考文献:https://www.cnblogs.com/libin-1/p/6893712.html 实现mvvm主要包含两个方面,数据变化更新视图,视图变化更新数据. 关键点在于data如何更新v ...

  3. EventBus事件总线框架(发布者/订阅者模式,观察者模式)

    一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. In ...

  4. C#事件支持发布者/订阅者模式(观察者模式)

    C#事件支持发布者/订阅者模式,发布者将事件通知给订阅者,而订阅者在事件发生时调用已经注册好的事件处理函数.        public delegate void delUpdate();  //委 ...

  5. 学习javascript设计模式之发布-订阅(观察者)模式

    1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...

  6. 用原生javascript实现最简单的发布者-订阅者模式

    http://www.cnblogs.com/surahe/p/6065778.html 发布—订阅模式可以广泛应用于异步编程中,这是一种替代传递回调函数的方案.比如,我们可以订阅 ajax 请求的 ...

  7. 发布者订阅者模式之JAVA实现

        1.发布者接口 package com.shoshana.publishsubscribe; public interface IPublisher<M> { public voi ...

  8. js中的观察者模式与发布者/订阅者模式的区别?

  9. .netcore利用DI实现订阅者模式 - xms

    结合DI,实现发布者与订阅者的解耦,属于本次事务的对象主体不应定义为订阅者,因为订阅者不应与发布者产生任何关联 一.发布者订阅者模式 发布者发出一个事件主题,一个或多个订阅者接收这个事件,中间通过事件 ...

随机推荐

  1. SPOJ - SUBLEX 【后缀自动机】

    题目 求第K小子串 题解 建好SAM后,拓扑排序,反向传递后面所形成的串的数量 最后从根开始,按照儿子形成串的数量与k比较走就好了 #include<iostream> #include& ...

  2. javascript作用域链理解

    执行上下文(Execution context,简称EC)   概念   每当控制器到达ECMAScript可执行代码的时候,就进入了一个执行上下文.   javascript中,EC分为三种:   ...

  3. 糗事百科python爬虫

    # -*- coding: utf-8 -*- #coding=utf-8 import urllib import urllib2 import re import thread import ti ...

  4. cxGrid让指定的某行自动呈选选中的状态

    cxView.ViewData.Rows[cxView.DataController.DataSource.DataSet.RecNo-1].Selected := True;//将当前的行呈选中的状 ...

  5. 传送带(bzoj 1857)

    Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度 ...

  6. HDU4305 Lightning

    There are N robots standing on the ground (Don't know why. Don't know how). Suddenly the sky turns i ...

  7. 【HDOJ5514】Frogs(容斥原理)

    题意:n个青蛙在一个有m个节点的圆上跳,m个节点的标号为0-m-1,每只青蛙每次跳的节点数给出,让求n只青蛙所跳位置标号之和 n<=1e4,m<=1e9,a[i]<=1e9 思路:由 ...

  8. EasyUI-Accordion

    EasyUI-Accordion Accordion英文翻译就是 手风琴活 或者 可折叠的 参考效果图: 从图中我们其实也可以将这种组件理解为手风琴式的组件. 该组件方便对数据进行分类管理,在有限空间 ...

  9. [LeetCode] Find Peak Element 二分搜索

    A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ ...

  10. js 验证数字的正则表达式集

    <script type="text/javascript">     function validate(){       var reg = new RegExp( ...