观察者模式 (Observer Pattern)

观察者模式其实在日常编码中经常遇到,比如DOM的事件监听,代码如下

  1. function clickHandler(event) {
  2. console.log('user click!');
  3. }
  4. document.body.addEventListener('click', clickHandler)

简而言之:观察者模式就如同上代码,有一个事件源‘dom 的click事件’ 也就是abservable,有一个观察者abserver clickHandler函数,有一个订阅机制(addEventLister),当dom的click事件触发时候,会通过订阅机制通知abserver 执行函数clickHandler函数。

下面是构建一个观察者模式的简单例子

  1. function Producer() {
  2. // 这个 if 只是避免使用者不小心把 Producer 当作函式来调用
  3. if(!(this instanceof Producer)) {
  4. throw new Error('请用 new Producer()!');
  5. // 仿 ES6 行为可用: throw new Error('Class constructor Producer cannot be invoked without 'new'')
  6. }
  7. this.listeners = [];
  8. }
  9. // 加入监听的方法
  10. Producer.prototype.addListener = function(listener) {
  11. if(typeof listener === 'function') {
  12. this.listeners.push(listener)
  13. } else {
  14. throw new Error('listener 必须是 function')
  15. }
  16. }
  17. // 移除监听的方法
  18. Producer.prototype.removeListener = function(listener) {
  19. this.listeners.splice(this.listeners.indexOf(listener), 1)
  20. }
  21. // 发送通知的方法
  22. Producer.prototype.notify = function(message) {
  23. this.listeners.forEach(listener => {
  24. listener(message);
  25. })
  26. }

接下来建立实例

  1. var egghead = new Producer();
  2. // new 出一个 Producer 实例叫 egghead
  3. function listener1(message) {
  4. console.log(message + 'from listener1');
  5. }
  6. function listener2(message) {
  7. console.log(message + 'from listener2');
  8. }
  9. egghead.addListener(listener1); // 注册监听
  10. egghead.addListener(listener2);
  11. egghead.notify('A new course!!') // 当某件事情方法时,执行
  12. //a new course!! from listener1
  13. //a new course!! from listener2

迭代器模式 (Iterator Pattern)

Iterator 是一个物件,它的就像是一个指针(pointer),指向一个资料结构并产生一个序列(sequence),这个序列会有资料结构中的所有元素(element)。

迭代者(Iterator,也称为“迭代器”)指的是能够遍历⼀个数据集合的对象,因为数据集合的实现⽅式很多,可以是⼀个数组,也可以是⼀个树形结构,也可以是⼀个单向链表……迭代器的作⽤就是提供⼀个通⽤的接口,让使⽤者完全不⽤关⼼这个数据集合的具体实现⽅式。

自己实现简单的迭代器

  1. function IteratorFromArray(arr) {
  2. if(!(this instanceof IteratorFromArray)) {
  3. throw new Error('请用 new IteratorFromArray()!');
  4. }
  5. this._array = arr;
  6. this._cursor = 0;
  7. }
  8. IteratorFromArray.prototype.next = function() {
  9. return this._cursor < this._array.length ?
  10. { value: this._array[this._cursor++], done: false } :
  11. { done: true };
  12. }

补充 - ES6 生成器

生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号可以紧挨着function关键字,也可以在中间添加一个空格

  1. // 生成器
  2. function *createIterator() {
  3. yield 1;
  4. yield 2;
  5. yield 3;
  6. }
  7. // 生成器能像正规函数那样被调用,但会返回一个迭代器
  8. let iterator = createIterator();
  9. console.log(iterator.next().value); // 1
  10. console.log(iterator.next().value); // 2
  11. console.log(iterator.next().value); // 3
  12. function *createIterator(items) {
  13. for (let i = 0; i < items.length; i++) {
  14. yield items[i];
  15. }
  16. }
  17. let iterator = createIterator([1, 2, 3]);
  18. console.log(iterator.next()); // "{ value: 1, done: false }"
  19. console.log(iterator.next()); // "{ value: 2, done: false }"
  20. console.log(iterator.next()); // "{ value: 3, done: false }"
  21. console.log(iterator.next()); // "{ value: undefined, done: true }"
  22. // 之后的所有调用
  23. console.log(iterator.next()); // "{ value: undefined, done: true }"

Observable 其实就是这两个 Pattern 思想的结合,Observable 具备生产者推送资料的特性,同时能像序列,拥有序列处理资料的方法(map, filter...)!

更简单的来说,Observable 就像是一个序列,裡面的元素会随著时间推送。

rxjs入门4之rxjs模式设计的更多相关文章

  1. RxJS入门2之Rxjs的安装

    RxJS V6.0+ 安装 RxJS 的 import 路径有以下 5 种: 1.创建 Observable 的方法.types.schedulers 和一些工具方法 import { Observa ...

  2. Android 腾讯入门教程( 智能手表UI设计 和 MVC模式 )

    *****注意到mvc 在android 中是如何进行分层分域执行各自的功能.**** 官方推荐的按钮尺寸是48像素 前端之Android入门(1):环境配置 前端之Android入门(2):程序目录 ...

  3. RxJS入门

    一.RxJS是什么? 官方文档使用了一句话总结RxJS: Think of RxJS as Lodash for events.那么Lodash主要解决了什么问题?Lodash主要集成了一系列关于数组 ...

  4. Rxjs入门实践-各种排序算法排序过程的可视化展示

    Rxjs入门实践-各种排序算法排序过程的可视化展示 这几天学习下<算法>的排序章节,具体见对排序的总结,想着做点东西,能将各种排序算法的排序过程使用Rxjs通过可视化的方式展示出来,正好练 ...

  5. 分享基于Entity Framework的Repository模式设计(附源码)

    关于Repository模式,在这篇文章中有介绍,Entity Framework返回IEnumerable还是IQueryable? 这篇文章介绍的是使用Entity Framework实现的Rep ...

  6. php模式设计之 观察者模式

    这是我写的<php模式设计>的第五篇.前面的四篇在不断学习不断加深认识,到了今天再看观察者模式,觉得非常容易理解.这也许就是我们积少成多的结果吧.希望还是能够不断进步. 开篇还是从名字说起 ...

  7. php模式设计之 适配器模式

    在这个有没有对象都要高呼“面向对象”的年代,掌握面向对象会给我们带来意想不到的方便.学编程的小伙伴从开始能写几行代码实现简单功能到后来懂得将一些重复的操作组合起来形成一个“函数”,再到后来将“函数”和 ...

  8. php模式设计之 注册树模式

    在前两篇单例模式和工厂模式后,终于迎来了最后一个基础的设计模式--注册树模式. 什么是注册树模式? 注册树模式当然也叫注册模式,注册器模式.之所以我在这里矫情一下它的名称,是因为我感觉注册树这个名称更 ...

  9. php模式设计之 工厂模式

    承接上篇php模式设计之 单例模式,(虽然好像关系不大).今天讲述第二种基础的模式设计——工厂模式. 那么何为工厂模式? 从名字来看,似乎看不出什么端倪.工厂模式,和生产有关?还是和生产流程有关?难道 ...

随机推荐

  1. hdu6704 2019CCPC网络选拔赛1003 K-th occurrence 后缀数组

    题意:给你一个长度为n的字符串,有q个询问,每次询问一个子串s(l,r)第k次出现的位置,若子串出现次数少于k次输出-1. 解题思路:先把SA跑出来,然后对于每次询问可以由l和rank[]找到l在所有 ...

  2. [译]如何在ASP.NET Core中实现面向切面编程(AOP)

    原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...

  3. 剑指 Offer 49. 丑数

    题目描述 我们把只包含质因子 2.3 和 5 的数称作丑数(Ugly Number).求按从小到大的顺序的第 n 个丑数. 示例: 输入: n = 10 输出: 12 解释: 1, 2, 3, 4, ...

  4. 在Oracle Sql Developer/Sql Plus中查看oracle版本

    输入select * from v$version; 执行即可. 此法在Sql plus中执行效果: SQL> select * from v$version; BANNER --------- ...

  5. ubuntu安装docker-ce 、docker-ce-cli、containerd.io

    问题 ubuntu安装docker的时候特别慢,百度搜了一大堆都没讲到点子上,最后请教了大佬才知道是源的问题 安装 修改源 sudo gedit /etc/apt/sources.list 添加源 阿 ...

  6. 如何使用 TDengine 2.0 最新开源的集群功能?

    导读:8月3日,TDengine 发布了 v2.0 版本,这次更新最大的亮点是,我们将分布式集群功能开源.开源后,引起了很大反响,又连续几天在 GitHub 趋势榜排名第一.不少关注TDengine的 ...

  7. C语言汇总2

    (10-15) 注释:1.单行注释可以嵌套单行注释 eg .//lalalal//lalalal(/后面都是注释完的) 2.多行注释可以嵌套单行注释 (两个**之间的都是注释的) 3.单行注释可以嵌套 ...

  8. vue2.5开发去哪儿了流程

    初始化项目 在 src/assets 中添加样式初始化文件 reset.css ; border.css 本地引入取消延迟300毫秒的控件 cnpm i fastclick -S 在mian.js中引 ...

  9. 理解Java中的final关键字

    final关键字的基本用法 1. 修饰类 出于安全考虑,类无法被继承 2. 修饰方法 防止继承类修改方法private方法会隐式指定为final方法: 3. 修饰变量 基本数据类型,初始化后不能再修改 ...

  10. netty字节分包

    高并发压测时,发现来自网关的消息出现粘包现象:分包就是势在必行的 前置和处理平台(暂时)使用netty通话,由于都是服务器平台使用DelimiterBasedFrameDecoder来解决分包 和网关 ...