js设计模式之观察者模式(发布-订阅模式)

简介: 前言 现实中的发布-订阅模式 小明最近看上了一套房子,到了售楼处之后才被告知,该楼盘的房子早已售罄。好在售楼MM告诉小明,不久后还有一些尾盘推出,开发商正在办理相关手续,手续办好后就可以购买。

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

  小明最近看上了一套房子,到了售楼处之后才被告知,该楼盘的房子早已售罄。好在售楼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);
目录
相关文章
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
338 124
|
JavaScript 前端开发 Docker
如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
通过这些步骤,可以确保您的Next.js应用在多核服务器上高效运行,并且在Docker环境中实现高效的容器化管理。
1443 44
|
设计模式 JavaScript 算法
浅谈几种js设计模式
设计模式是软件开发中的宝贵工具,能够提高代码的可维护性和扩展性。通过单例模式、工厂模式、观察者模式和策略模式,我们可以解决不同场景下的实际问题,编写更加优雅和高效的代码。
396 8
Next.js 实战 (三):优雅的实现暗黑主题模式
这篇文章介绍了在Next.js中实现暗黑模式的具体步骤。首先,需要安装next-themes库。然后,在/components/ThemeProvider/index.tsx文件中新增ThemeProvider组件,并在/app/layout.tsx文件中注入该组件。如果想要加入过渡动画,可以修改代码实现主题切换时的动画效果。最后,需要在需要的位置引入ThemeModeButton组件,实现暗黑模式的切换。
535 0
Next.js 实战 (三):优雅的实现暗黑主题模式
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
254 2
|
前端开发 JavaScript UED
探索JavaScript的异步编程模式
【10月更文挑战第40天】在JavaScript的世界里,异步编程是一道不可或缺的风景线。它允许我们在等待慢速操作(如网络请求)完成时继续执行其他任务,极大地提高了程序的性能和用户体验。本文将深入浅出地探讨Promise、async/await等异步编程技术,通过生动的比喻和实际代码示例,带你领略JavaScript异步编程的魅力所在。
161 1
|
前端开发 JavaScript UED
探索JavaScript中的异步编程模式
【10月更文挑战第21天】在数字时代的浪潮中,JavaScript作为一门动态的、解释型的编程语言,以其卓越的灵活性和强大的功能在Web开发领域扮演着举足轻重的角色。本篇文章旨在深入探讨JavaScript中的异步编程模式,揭示其背后的原理和实践方法。通过分析回调函数、Promise对象以及async/await语法糖等关键技术点,我们将一同揭开JavaScript异步编程的神秘面纱,领略其带来的非阻塞I/O操作的魅力。让我们跟随代码的步伐,开启一场关于时间、性能与用户体验的奇妙之旅。
|
JavaScript 前端开发 API
探索Node.js中的异步编程模式
【10月更文挑战第4天】在JavaScript的世界中,异步编程是提升应用性能和用户体验的关键。本文将深入探讨Node.js中异步编程的几种模式,包括回调函数、Promises、async/await,并分享如何有效利用这些模式来构建高性能的后端服务。
141 2
|
前端开发 JavaScript UED
探索JavaScript的异步编程模式
【10月更文挑战第33天】在JavaScript的世界里,异步编程是提升应用性能和用户体验的关键。本文将带你深入理解异步编程的核心概念,并展示如何在实际开发中运用这些知识来构建更流畅、响应更快的Web应用程序。从回调函数到Promises,再到async/await,我们将一步步解锁JavaScript异步编程的秘密,让你轻松应对各种复杂的异步场景。
|
11月前
|
设计模式 Java 数据库连接
【设计模式】【创建型模式】工厂方法模式(Factory Methods)
一、入门 什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法模式使类的实例化延迟
315 16

热门文章

最新文章