RxJS 中的观察者和迭代器模式
目录
- 前言
- 观察者模式
- 迭代器模式
- RxJS 中两种模式的结合和实现
- 小结
- 参考
1. 前言
RxJS 是一个库,它通过使用observable(可观察对象)序列来编写异步和基于事件的程序。其结合了观察者模式、迭代器模式和使用集合的函数式编程,以一种理想方式来管理事件序列所需要的一切。
本文将主要探讨观察者模式、迭代器模式以及它们如何在 RxJS 中被应用。
2. 观察者模式
实现了生产者(事件的创建者)和消费者(事件的监听者)的逻辑分离关系。
浏览器 DOM 事件的监听和触发应该是 Web 前端最典型的观察者模式的实现。
document.body.addEventListener('click', function listener(e) {
console.log(e);
});
document.body.click(); // 模拟用户点击
监听:通过addEventListener给 document.body节点绑定一个click事件的事件处理函数。
触发:当用户点击页面(body)时,body节点将会触发绑定的事件处理函数。
关系图如下:

3. 迭代器模式
可以让用户通过特定的接口访问集合中的每一个元素而不用了解底层的实现。
从 ES 6 开始,引入的一种新的遍历机制——迭代器,其就是迭代器模式在 JavaScript 中的一种实现。在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。 更具体地说,迭代器是通过使用 next() 方法实现 Iterator protocol (迭代器协议)的任何一个对象,该方法返回具有两个属性的对象: value和done ,其中value代表具体返回值,done表示是否已经迭代完毕。
String、Array、Map 和 Set 等都是内置可迭代对象,它们的原型对象都拥有一个 Symbol.iterator 方法。
const arr = ['a', 'b'];
const iterator = arr[Symbol.iterator](); // 获取迭代器对象
iterator.next(); // { value: 'a', done: false }
iterator.next(); // { value: 'b', done: false }
iterator.next(); // { value: undefined, done: true }
我们常常用for-of 循环来遍历可迭代对象:
const arr = ['a', 'b'];
for (let value of arr) {
console.log(value); // a b
}
for-of语法是为了方便遍历可迭代对象,其内部实现调用的是Symbol.iterator方法,类似下面的代码:
const arr = ['a', 'b'];
const iterator = arr[Symbol.iterator]();
let result = iterator.next();
while (!result.done) {
console.log(result.value); // a b
result = iterator.next();
}
迭代器的特点:
- 访问集合中的内容而不用了解底层的实现。
- 提供了一个统一的接口遍历不同的集合结构,从而支持同样的算法在不同的集合结构上进行操作。
4. RxJS 中两种模式的结合和实现
RxJS 中包含两个基本概念:**Observable **和 Observer。
Observable 作为可观察对象(被观察者),是一个可调用的未来值或事件的集合(异步或同步数据流)。
Observer 作为观察者,是一个回调函数的集合,它知道如何去监听由Observable提供的值。
Observable和Observer之间的订阅发布关系(观察者模式)如下:
订阅:Observer 通过 Observable 提供的 subscribe() 方法订阅 Observable。
发布:Observable 通过 Observer 提供的 next 方法向 Observer 发布事件。
两者关系的伪代码如下:
// Observer
const observer = {
next(value) {
console.log(value);
}
};
// Observable
function Observable (observer) {
setTimeout(()=>{
observer.next('A');
}, 1000);
}
// subscribe
Observable(observer);
从上可知,所谓订阅,就是将观察者Observer注入到可观察对象Observable中。
在 RxJS 中,Observer 除了有 next 方法来接收 Observable 的事件外,还提供了另外的两个方法:error() 和 complete(),来处理异常和完成状态。
const observer = {
next(value) { /* 处理值 */ },
error(err) { /* 处理异常 */ },
complete() { /* 处理已完成态 */ }
};
结合迭代器 Iterator 来理解Observer的三个方法:
- next():
Observer通过提供next方法来接受Observable流(集合),是一种push形式(推送)。- 对比
Iterator,则是通过调用iterator.next()拿值,是一种pull的形式(拉取)。
- 对比
- complete():当不再有新的值发出时,将触发
Observer的complete方法。- 对比
Iterator,则是在next()的返回结果中的done为true时,则表示complete。
- 对比
- error():当处理事件中出现异常时,通过
try-catch捕获异常,Observer提供error方法来接收错误进行统一处理。
一个简单的 RxJS 订阅-发布实例:
import { Observable } from 'rxjs';
const observable = new Observable(function (observer) {
// 通知观察者
observer.next('a');
observer.next('b');
observer.complete(); // 将取消该观察者的订阅
// observer.error(new Error('err'));
observer.next('c'); // 由于已经 complete,所以不会再发送
});
// 定义观察者,next、complete、error 方法处理流的不同状态
const observer = {
next: (value) => console.log(value),
error: err => console.error('Observer got an error: ' + err),
complete: () => console.log('Observer got a complete notification')
}
// 订阅 Observable 并执行
const subscription = observable.subscribe(observer); // 将返回一个可取消的订阅对象 subscription
执行结果:
a
b
5. 小结
一句话概述 RxJS 中实现的观察者+迭代器模式:就是将观察者Observer注入到可观察对象Observable中,然后在可观察对象Observable中通过调用Observer提供的 next、complete、error 方法处理流的不同状态,以实现对数据流的一种顺序访问处理。
6. 参考
RxJS 中的观察者和迭代器模式的更多相关文章
- 迭代器模式的一种应用场景以及C#对于迭代器的内置支持
迭代器模式 先放上gof中对于迭代器模式的介绍镇楼 意图 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示. 别名 游标(Cursor). 动机 一个聚合对象, 如列表(li ...
- (十七)迭代器模式详解(foreach的精髓)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,很久没以LZ的身份和 ...
- 设计模式之迭代器模式详解(foreach的精髓)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,很久没以LZ的身份和 ...
- js设计模式(四)---迭代器模式
定义: 迭代器模式是指提供一种方法,顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示,迭代器模式可以把迭代的过程从业务逻辑中分离出来,使用迭代器模式,即使不关心对象的内部构造,也可以按 ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- java设计模式之迭代器模式
一.迭代器模式简介 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露内部的表示.把游走的任务放在迭代器上,而不是 ...
- 十七:迭代器模式详解(foreach的精髓)
定义:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 从定义中可以看出,迭代器模式是为了在不暴露该对象内部表示的情况下,提供一种顺序访问聚合对象中元素的方法.这种思想在JA ...
- 行为型模式(三) 迭代器模式(Iterator)
一.动机(Motivate) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素:同时这种"透明 ...
- Java迭代器模式
迭代器模式是Java和.Net编程环境中非常常用的设计模式.此模式用于以顺序方式访问集合对象的元素,而不需要知道其底层表示. 迭代器模式属于行为模式类别. 实现实例 在这个实例中,将创建一个Itera ...
随机推荐
- 一文搞懂Python函数(匿名函数、嵌套函数、闭包、装饰器)!
Python函数定义.匿名函数.嵌套函数.闭包.装饰器 目录 Python函数定义.匿名函数.嵌套函数.闭包.装饰器 函数核心理解 1. 函数定义 2. 嵌套函数 2.1 作用 2.2 函数变量作用域 ...
- 数据可视化之powerBI基础(十八)Power BI度量值的格式如何修改?这里有三种方式
https://zhuanlan.zhihu.com/p/99818030 在知识星球遇到的问题中,有不少朋友问如何修改数值型度量值的格式,比如,新建的度量值如何显示为百分比或者千分位等等,这篇文章 ...
- Integer和Long部分源码分析
Integer和Long的java中使用特别广泛,本人主要一下Integer.toString(int i)和Long.toString(long i)方法,其他方法都比较容易理解. Integer. ...
- node最简单的本地服务搭建
**1.首先需要安装node** [node下载链接](http://nodejs.cn/download/)**2.需要安装http的镜像文件** npm install http-server - ...
- Python爬虫学习02--pyinstaller
Python爬虫学习02--打包exe可执行程序 1.上一次做了一个爬虫爬取电子书的Python程序,然后发现可以通过pyinstaller进行打包成exe可执行程序.发现非常简单好用 2.这是上次写 ...
- kafka零拷贝
Kafka之所以那么快的另外一个原因就是零拷贝(zero-copy)技术.本文我们就来了解Kafka中使用的零拷贝技术为什么那么快. 传统的文件拷贝 传统的文件拷贝通常需要从用户态去转到核心态,经过r ...
- 详解UDP协议
运输层位于网络层之上,网络层提供了主机之间的逻辑通信:而运输层为运行在不同主机上的应用进程之间提供了逻辑通信.从应用程序角度看,通过逻辑通信,运行不同进程的主机好像直接相连一样.应用进程使用运输层提供 ...
- UVA 10653.Prince and Princess
题目 In an n * n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbe ...
- 题解 洛谷 P3185 【[HNOI2007]分裂游戏】
首先可以发现,当所有巧克力豆在最后一个瓶子中时,就无法再操作了,此时为必败状态. 注意到,对于每个瓶子里的巧克力豆,是可以在模\(2\)的意义下去考虑的,因为后手可以模仿先手的操作,所以就将巧克力豆个 ...
- xenomai内核解析---内核对象注册表—xnregistry(重要组件)
1. 概述 上篇文章xenomai内核解析--同步互斥机制(一)--优先级倒置讲到,对于所有内核对象: xnregistry:保存内核对象,提供内核对象存储和快速检索. xnsynch:资源抽象,提供 ...