Javascript模式(二) 发布者/订阅者模式
var publisher = {
// 订阅者数组
subscribers : {
"any" : []
},
// 增加订阅者
on : function(type, fn, context){
var subscribers = this.subscribers;
type = type || "any";
context = context || this;
fn = typeof fn === "function" ? fn : context[fn];
if(!subscribers[type]){
subscribers[type] = [];
}
subscribers[type].push({"fn" : fn, "context" : context});
},
// 移除订阅者
off : function(type, fn, context){
this.visit("unPublish", type, fn, context)
},
// 通知
fire : function(type, arg){
this.visit("publish", type, arg);
},
// 访问订阅者数组
visit : function(action, type, arg, context){
var subscribers, i, len;
type = type || "any";
subscribers = this.subscribers[type];
len = subscribers.length || 0;
switch(action){
case "publish" :
for(i = 0; i < len; i++){
subscribers[i].fn.call(subscribers[i].context, arg);
}
break;
case "unPublish":
for(i = 0; i < len; i++){
if(subscribers[i].fn === arg && subscribers[i].context === context){
subscribers.splice(i, 1);
}
}
break;
}
}
};
function makePublisher(o){
o.subscribers = {"any" : []};
for(var p in publisher ){
if(publisher.hasOwnProperty(p) && typeof publisher[p] === "function"){
o[p] = publisher[p];
}
}
return o;
}
// 发布者Play
// 发布两个事件:1、有玩家加入 2、玩家开始玩
function Player(name, key){
this.point = 0;
this.name = name;
this.key = key;
this.fire("add", this);
}
Player.prototype.play = function(){
this.point += 1;
this.fire("play", this);
};
// 观察者/订阅者 game,观察2个事件:1、有玩家加入 2、玩家开始玩
// 同时作为发布者game,通知积分榜更新
var game = {
// 存储对象和按键key的关系
keys : {},
// 订阅
addPlayer : function(player){
this.keys[player.key] = player;
},
// 通知订阅者scoreboard更新
handlyPlay : function(){
var score = {}, keys = this.keys, p;
for(p in keys){
if(keys.hasOwnProperty(p)){
score[keys[p].name] = keys[p].point;
}
}
this.fire("update", score);
},
// 封装keypress事件
keydown : function(e){
var which, code;
e = e || event;
which = e.which || e.keyCode;
code = String.fromCharCode(which);
if(this.keys[code]){
this.keys[code].play();
}
}
};
// 积分榜
var scoreboard = {
dom : document.getElementById("score_board"),
// 更新积分榜 参数格式 {playname1 : point, playname2 : point }
update : function(score){
var p, html = "";
for(p in score){
if(score.hasOwnProperty(p)){
html += p + "获得了" + score[p] + "<br/>";
}
}
this.dom.innerHTML = html;
}
};
// Player作为发布者,因其需要通知订阅者game新增玩家以及玩家积分变化
// game对Player而言是订阅者,因其需要订阅Player的特定活动add(新增玩家)和play(玩家积分发生变化)
// game对scoreboard而言是发布者,因其在观察到Player的play事件之后需要通知scoreboard更新积分
makePublisher(Player.prototype);
makePublisher(game);
Player.prototype.on("add", game.addPlayer, game);
Player.prototype.on("play", game.handlyPlay, game);
game.on("update", scoreboard.update, scoreboard);
//excute
while(true){
var name = prompt("say your name, man"), key;
if(name && name !== "null"){
while(true){
key = prompt("what is your key");
if(key && key !== "null"){
break;
}
alert("亲,还是指定个key吧,不然你没办法玩的,相信我");
}
new Player(name, key);
}
else {
break;
}
}
document.onkeydown = function(e){
game.keydown.call(game, e);
};
Javascript模式(二) 发布者/订阅者模式的更多相关文章
- JavaScript 设计模式: 发布者-订阅者模式
JavaScript 设计模式: 发布者-订阅者模式 发布者-订阅者模式 https://github.com/Kelichao/javascript.basics/issues/22 https:/ ...
- vue双向绑定(数据劫持+发布者-订阅者模式)
参考文献:https://www.cnblogs.com/libin-1/p/6893712.html 实现mvvm主要包含两个方面,数据变化更新视图,视图变化更新数据. 关键点在于data如何更新v ...
- EventBus事件总线框架(发布者/订阅者模式,观察者模式)
一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. In ...
- C#事件支持发布者/订阅者模式(观察者模式)
C#事件支持发布者/订阅者模式,发布者将事件通知给订阅者,而订阅者在事件发生时调用已经注册好的事件处理函数. public delegate void delUpdate(); //委 ...
- 学习javascript设计模式之发布-订阅(观察者)模式
1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...
- 用原生javascript实现最简单的发布者-订阅者模式
http://www.cnblogs.com/surahe/p/6065778.html 发布—订阅模式可以广泛应用于异步编程中,这是一种替代传递回调函数的方案.比如,我们可以订阅 ajax 请求的 ...
- 发布者订阅者模式之JAVA实现
1.发布者接口 package com.shoshana.publishsubscribe; public interface IPublisher<M> { public voi ...
- js中的观察者模式与发布者/订阅者模式的区别?
- .netcore利用DI实现订阅者模式 - xms
结合DI,实现发布者与订阅者的解耦,属于本次事务的对象主体不应定义为订阅者,因为订阅者不应与发布者产生任何关联 一.发布者订阅者模式 发布者发出一个事件主题,一个或多个订阅者接收这个事件,中间通过事件 ...
随机推荐
- java的图像界面
package test; import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.even ...
- Chrome 浏览器访问 Google 学术出现问题 “but your computer or network may be sending automated queries. ”
问题: Chrome 浏览器访问 Google 学术出现如下的问题 : ... but your computer or network may be sending automated querie ...
- 分布式文件系统FastDFS集群部署
1.源码开放下载地址:https://github.com/happyfish100 早期源码开放下载地址:https://sourceforge.net/projects/fastdfs/files ...
- 【转】Nodejs学习笔记(二)--- 模块
目录 简介及资料 自定义模块 创建一个自定义模块 调用自定义模块 exports和module.exports 区别 exports和module.exports 覆盖 其它... 简介及资料 通过N ...
- 回文串(bzoj 3676)
Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行 ...
- Repeater用ul li,一行显示多条数据
原文发布时间为:2009-08-26 -- 来源于本人的百度文章 [由搬家工具导入] .rep { width:680px; float:left; l ...
- 一个简单有效的兼容IE7浏览器的办法
最近发现了一个简单有效的兼容IE7浏览器的办法 直接将下面代码复制道页面 <meta http-equiv="X-UA-Compatible" content="I ...
- JAVA中的编码分析
在实际编程中可以不用关注JVM中使用的是什么编码,而只需要关注自己输出需要采用的编码,JVM会根据你设置的编码正确操作. 1.String采用的是什么编码? 很多厂家根据规范实现了JVM,JVM只说明 ...
- 10.1综合强化刷题 Day6
T1 排序 题目描述 小Z 有一个数字序列a1; a2; .... ; an,长度为n,小Z 只有一个操作:选 定p(1<p<n),然后把ap 从序列中拿出,然后再插⼊到序列中任意位置. ...
- Hdoj 2509 Be the Winner
Diciption Let's consider m apples divided into n groups. Each group contains no more than 100 apples ...