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,实现发布者与订阅者的解耦,属于本次事务的对象主体不应定义为订阅者,因为订阅者不应与发布者产生任何关联 一.发布者订阅者模式 发布者发出一个事件主题,一个或多个订阅者接收这个事件,中间通过事件 ...
随机推荐
- SPOJ - SUBLEX 【后缀自动机】
题目 求第K小子串 题解 建好SAM后,拓扑排序,反向传递后面所形成的串的数量 最后从根开始,按照儿子形成串的数量与k比较走就好了 #include<iostream> #include& ...
- javascript作用域链理解
执行上下文(Execution context,简称EC) 概念 每当控制器到达ECMAScript可执行代码的时候,就进入了一个执行上下文. javascript中,EC分为三种: ...
- 糗事百科python爬虫
# -*- coding: utf-8 -*- #coding=utf-8 import urllib import urllib2 import re import thread import ti ...
- cxGrid让指定的某行自动呈选选中的状态
cxView.ViewData.Rows[cxView.DataController.DataSource.DataSet.RecNo-1].Selected := True;//将当前的行呈选中的状 ...
- 传送带(bzoj 1857)
Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度 ...
- HDU4305 Lightning
There are N robots standing on the ground (Don't know why. Don't know how). Suddenly the sky turns i ...
- 【HDOJ5514】Frogs(容斥原理)
题意:n个青蛙在一个有m个节点的圆上跳,m个节点的标号为0-m-1,每只青蛙每次跳的节点数给出,让求n只青蛙所跳位置标号之和 n<=1e4,m<=1e9,a[i]<=1e9 思路:由 ...
- EasyUI-Accordion
EasyUI-Accordion Accordion英文翻译就是 手风琴活 或者 可折叠的 参考效果图: 从图中我们其实也可以将这种组件理解为手风琴式的组件. 该组件方便对数据进行分类管理,在有限空间 ...
- [LeetCode] Find Peak Element 二分搜索
A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ ...
- js 验证数字的正则表达式集
<script type="text/javascript"> function validate(){ var reg = new RegExp( ...