博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js设计模式之观察者模式(发布-订阅模式)
阅读量:6458 次
发布时间:2019-06-23

本文共 2979 字,大约阅读时间需要 9 分钟。

前言 现实中的发布-订阅模式

小明最近看上了一套房子,到了售楼处之后才被告知,该楼盘的房子早已售罄。好在售楼MM告诉小明,不久后还有一些尾盘推出,开发商正在办理相关手续,手续办好后就可以购买。但到底什么时候,目前还没有人知道。  于是小明记下了售楼处的电话,以后每天都会打电话过去询问是不是到了购买时间。除了小明,还有小红、小强、小龙也会每天向售楼处咨询这个问题。一个星期后,售楼MM决定辞职,因为厌倦了每天回答1000个相同内容的电话。  当然现实中没有这么笨的售楼公司,实际上故事是这样的:小明离开之前,把电话号码留在了售楼处。售楼MM答应他,新楼盘一推出就马上发信息通知小明。小红、小强、小龙也是一样,他们的电话号码都被记在售楼处的花名册上,新楼盘推出的时候,售楼MM会翻开花名册,遍历上面的电话号码,依次发送一条短信来通知他们。

一、最简单的例子

// 订阅信息document.body.addEventListener('click', function(){    alert(1);},false);// 订阅信息document.body.addEventListener('click', function(){    alert(2);},false);// 发布消息document.body.click();

document.body订阅了click事件,然后当它被点击(发布)的时候,接收到了信息。

二、发布-订阅模式的模式简单实现

// 定义售楼处var salesOffices = {};// 售楼花名册salesOffices.clientList = [];// 订阅售楼消息的函数salesOffices.listen = function (fn) {    this.clientList.push(fn);}// 发布售楼消息的函数salesOffices.trigger = function () {    // 遍历花名册,给留了电话号码的客户发送信息    for (var i = 0, fn; fn = this.clientList[i++];) {        debugger;        fn.apply(this, arguments);    }}// 小明订阅售楼信息salesOffices.listen(function (price) {    console.log('price=' + price);});// 小红订阅售楼信息salesOffices.listen(function (price) {    console.log('price=' + price);});// 售楼处发布售楼信息salesOffices.trigger('squareMeter88', 200000);salesOffices.trigger('squareMeter110', 300000);

简单的发布-订阅模式存在一个缺陷:就是如果小明只想订阅88平米的楼盘,但是售楼处会把所有的楼盘信息都推送给了他。我们可以做得更智能一些,给订阅的函数多传一个参数,表明订阅者只订阅那一个消息。

三、发布-订阅模式的模式进阶实现

// 定义售楼处var salesOffices = {};// 定义客户花名册salesOffices.clientList = [];// 定义订阅方法salesOffices.listen = function (key, fn) {    // 花名册登记哪些客户订阅哪些信息(根据key来区分)    if (!this.clientList[key]) {        this.clientList[key] = [];    }    this.clientList[key].push(fn);}salesOffices.trigger = function () {    // 获取key,获取第一个参数    var key = Array.prototype.shift.call(arguments);    var fns = this.clientList[key];    if (!fns || fns.length === 0) {        return false;    }    for (var i = 0, fn; fn = fns[i++];) {        fn.apply(this, arguments);    }}// 小明定于88平米的楼盘salesOffices.listen('squareMeter88', function (price) {    console.log('price=' + price);});// 小红定于100平米的楼盘salesOffices.listen('squareMeter100', function (price) {    console.log('price=' + price);});// 售楼处发布楼盘信息salesOffices.trigger('squareMeter88', 2000000);salesOffices.trigger('squareMeter100', 3000000);

四、封装订阅-发布模式

var event = {    clientList: [],    listen: function(key, fn) {        if (!this.clientList[key]) {            this.clientList[key] = [];        }        this.clientList[key].push(fn);    },    trigger: function() {        var key = Array.prototype.shift.call(arguments);        var fns = this.clientList[key];        if (!fns || fns.length === 0) {            return false;        }        for (var i=0,fn;fn=fns[i++];) {            fn.apply(this, arguments);        }    }}function installEvent(obj) {    for (var i in event) {        obj[i] = event[i];    }}var salesOffices = {};installEvent(salesOffices);salesOffices.listen('squareMeter88', function(price) {    console.log(`price=${price}`);  });salesOffices.trigger('squareMeter88',200000);

转载地址:http://zlizo.baihongyu.com/

你可能感兴趣的文章
用CSS border相关属性画三角形
查看>>
ubuntu分区
查看>>
iOS图片拉伸技巧
查看>>
director.js教程
查看>>
Python基础之内置函数(二)
查看>>
Code First开发系列之数据库迁移
查看>>
windows下dump文件调试
查看>>
【设计模式】单例模式
查看>>
java发送http的get、post请求
查看>>
Spring配置bean文件的底层实现方式
查看>>
软件魔方制作系统启动盘并安装win10系统
查看>>
【PHP面向对象(OOP)编程入门教程】20.PHP5接口技术(interface)
查看>>
Eclipse修改XML默认打开方式
查看>>
okHttp3自用封装
查看>>
走进缓存的世界(二) - 缓存设计
查看>>
JQuery 之 跳出循环
查看>>
数据库面试(四)
查看>>
SharePoint Backup
查看>>
网站统计功能的设计与实现
查看>>
neutron用linux_bridge部署provider网络
查看>>