RxJS 操作符-学习笔记

提前准备:

  • pipe 方法: 用于组合多个操作符,可以将一系列操作符作为参数传递给 pipe 方法,这些操作符将 依次 对数据流进行处理。这里的依次很关键,也代表着pipe()中组合的这么几个操作符的执行顺序就是从开始一直到结束的,其中的数据会同流水线一般在各个操作符中进行传递。上一个操作符把数据处理好了,会自动地把这个处理好的数据送给下一个操作符接收,基于这个在上一步处理过的数据再进行进一步的加工,如此往复,直到执行到最后一个操作符为止。
  •  RxJS通过提供一种 统一的方式 来处理异步和基于事件的程序。这种统一的方式就是基于它的核心思想: 将一切都视为随时间变化的数据流 ,从而能够用更加函数式和响应式的方式来处理复杂的数据处理问题。实际实现的时候,其实就是把所有的数据流、事件全都转成 Observable ,然后再在这个 Observable 的基础上进行订阅消息,实现对其发布的数据的处理。
  • 观察者模式(Observer Pattern)是一种设计模式,其中一个对象(称为“主题”或“可观察对象”)维护一组观察者,当该对象状态变化时,会自动通知所有观察者。
  • Observables(可观察对象):在RxJS中,Observables就是这样的“主题”。它代表了一个可观察的数据流或异步事件流。
  • Observers(观察者):观察者是一个包含回调函数集合的对象,这些函数决定了如何响应Observable发送的数据或事件。
  • 订阅(Subscribe):观察者通过“订阅”Observable来接收数据和通知。当Observable发出数据时,会调用观察者的回调函数(例如:next, error, complete)。简写observable.subscribe(x => console.log('Observer got a next value: ' + x));
  • Observable 的懒加载:这表示 Observable 不会在创建时立即开始工作,而是在被订阅(subscribe)时才开始执行 。当你创建一个 Observable 实例时,你仅仅是 定义了一个数据流和如何生成这些数据的规则 。此时,数据流并不会立即开始。只有当 Observable 被某个观察者订阅时,定义在 Observable 构造函数中的函数(订阅函数)才会 被执行 。这个函数负责产生数据并通过 nexterror, 和 complete 方法发送给观察者。每当有新的订阅发生时,Observable 会从头开始执行其定义的逻辑。这意味着每个订阅者都有自己的数据流实例,互不影响。

一、组合

forkJoin

当有一组 observables,但你只关心每个 observable 最后发出的值时,此操作符是最适合的。此操作符的一个常见用例是在页面加载(或其他事件)时你希望发起多个请求,并在所有请求都响应后再采取行动。
当所有 observables 完成时,将每个 observable  的最新值作为数组发出。
如果内部 observable 不完成的话,forkJoin 永远不会发出值!

const example = forkJoin( of('Hello'),// 立即发出 'Hello'of('World').pipe(delay(1000)),// 1秒后发出 'World'
);
const subscribe = example.subscribe(val => console.log(val));//输出: ["Hello", "World"]//发送请求forkJoin(this._myService.myRequest('Request One', 2000),this._myService.myRequest('Request Two', 1000),this._myService.myRequest('Request Three', 3000)).subscribe(([res1, res2, res3]) => {this.propOne = res1;this.propTwo = res2;this.propThree = res3;});

二、转换

1、mergeMap(fn):

功能:类似于 switchMap,但它不会取消之前的 Observables,而是合并所有的 Observables。
应用场景:当你需要处理每个值并同时保持所有结果时使用。

将内部 多个 observable,打平成一个observable,可以 使用mergeMap。

//将每个字母映射并打平成一个 Observable ,每1秒钟一次var letters = Rx.Observable.of('a', 'b', 'c');
var result = letters.mergeMap(x =>Rx.Observable.interval(1000).map(i => x+i)
);
result.subscribe(x => console.log(x));// 结果如下:
// a0
// b0
// c0
// a1
// b1
// c1
// 继续列出a、b、c加上各自的自增数列

另外需要注意:

  1. 如果一次只能激活一个内部订阅,请使用 switchMap。
  2. 如果内部 observables 的发射和订阅顺序很重要,请使用 concatMap.

当使用 switchMap 时,每个内部订阅在源发出时完成,即任意时间段只允许一个活动的内部订阅。相比之下,mergeMap 允许同时激活多个内部订阅。因此,mergeMap 最常见的用例之一是不应取消的请求,这些请求被认为是写入而不是读取。请注意,如果这些写入必须保持顺序,则 concatMap 是更好的选择。比如数据库的写操作。

由于 mergeMap 一次维护多个活动的内部订阅,因此可能会由于长期存在的内部订阅造成内存泄漏。一个基本的例子是,如果使用内部计时器或 dom 事件流映射到可观察对象。在这些情况下,如果仍然希望使用 mergeMap,一个好办法是利用另一个运算符来管理内部订阅的完成,比如考虑 take 或 takeUntil。当然还可以使用 concurrent 参数限制一次活动内部订阅的数量。

2、map(fn):

功能:将数据流中的每个值通过函数 fn 进行转换。
应用场景:当你需要修改数据流中的每个值时使用,例如将数据流中的数字乘以2。

3、switchMap(fn):

功能:对数据流中的每个值应用函数 fn,并将结果转换为新的 Observable,当新的值到来时,会取消之前的 Observable。
应用场景:处理级联数据流,如基于当前值获取新的数据。

三、过滤

1、filter(fn):

功能:根据函数 fn 的条件判断,决定是否保留数据流中的每个值。
应用场景:用于筛选数据流,例如过滤出偶数。

// 每1秒发出值
const source = interval(1000);// 过滤掉所有值知道 interval 发出的值大于5
const example = source.pipe(filter(num => num > 5));const subscribe = example.subscribe(val =>console.log(`${val}`) //输出 6 7 8 9
);

2、take(count):

功能:只取数据流的前 count 个值,然后完成。
应用场景:限制数据流的长度,如只取前5个值。

3、first():

功能:只取数据流的第一个值,然后完成。
应用场景:当你只对数据流的第一个值感兴趣时使用。


4、last():

功能:只取数据流的最后一个值,然后完成。
应用场景:当你只对数据流的最后一个值感兴趣时使用。

5、debounceTime(ms):

功能:在指定的毫秒数 ms 后,只发出最新的值,如果在这段时间内有新值产生,则重新计时。
应用场景:处理高频事件,如键盘输入。

//舍弃掉在两次输出之间小于指定时间的发出值const input = document.getElementById('example');// 对于每次键盘敲击,都将映射成当前输入值
const example = fromEvent(input, 'keyup').pipe(map(i => i.currentTarget.value));// 在两次键盘敲击之间等待0.5秒方才发出当前值,
// 并丢弃这0.5秒内的所有其他值
const debouncedInput = example.pipe(debounceTime(500));// 输出值
const subscribe = debouncedInput.subscribe(val => {console.log(`Debounced Input: ${val}`);
});


6、throttleTime(ms):

功能:在每个时间窗口 ms 的开始,发出最新的值。
应用场景:限制数据流的速率,例如在滚动事件中。

四、错误处理

1、catchError(fn):

功能:捕获错误,并通过函数 fn 提供一种处理错误的方式。
应用场景:错误处理。

五、创建

1、of(...values):

用于创建一个 Observable,它会依次发出提供的参数,然后完成。
例如:of(1, 2, 3) 会依次发出 1, 2, 3。


2、from(iterable):

将数组、类数组对象、Promise 或迭代器转换为 Observable。
例如:from([1, 2, 3]) 会依次发出 1, 2, 3。


3、interval(period):

创建一个 Observable,它按照指定的时间间隔连续发出数字序列。
例如:interval(1000) 每隔1秒发出一个递增的数字。


4、timer(initialDelay, period):

在给定的初始延迟之后,发出数字0,然后如果指定了周期,将继续以该周期发出递增的数字。
例如:timer(3000, 1000) 在3秒后发出0,然后每隔1秒发出一个递增的数字。


5、fromEvent(target, eventName):

从DOM事件、Node.js EventEmitter 事件或其他事件源创建 Observable。
例如:fromEvent(document, 'click') 用于从文档的点击事件创建 Observable。


6、ajax(urlOrRequest):

用于创建一个 Observable,以发出针对URL的Ajax请求的响应。
例如:ajax('/api/data') 会发出对 /api/data 的Ajax请求的响应。


7、create(subscribe):

传统的方式来创建一个新的 Observable,通过提供一个 subscribe 函数。
例如:new Observable(subscriber => {...})。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/600088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql 将表里的两列值数据互换

示例: 需要将表中的 两个订单号互换 方案: 将同一张表数据做 临时数据 和主表 做数据交互 。 update 表 as main, 表 as temp set main.bill_no temp.track_bill_no, main.track_bill_no temp.bill_no where main.id temp.id…

小白的2023总结与未来的妄想

嘿,各位,很高兴各位能看到这篇文章,先祝各位家人2024财源茂盛达三江,生意兴隆通四海!!!! 那么作为一个还在读大三的入门小白,这一年得益于身边的各个校外大佬与校内老师的…

【Oracle数据库】两个服务端通过一个端口分别读写两个数据库账户下的表

允许两个服务端文件通过一个端口分别读写两个数据库账户下的表格数据,并且这两个用户名下的表格数据在一个表空间! Q:一个Oracle表空间中两个用户下面的表,我用服务端写入和读取这两个用户下面的表格时,可以用一样的端…

test coverate-04-测试覆盖率 Cobertura Cobertura/emma/jacoco 的差异对比?

拓展阅读 test 系统学习-04-test converate 测试覆盖率 jacoco 原理介绍 test 系统学习-05-test jacoco 测试覆盖率与 idea 插件 test 系统学习-06-test jacoco 关于 Cobertura Cobertura是一个免费的Java代码覆盖率报告工具,基于jcoverage 1.0.5。详细信息请参…

新手小白如何搭建自己的服务器

由于近期六年前的域名到期了,阿里云的客服电话,正好提醒了我需要管理下这方面的东西, 正好看到阿里云的服务器99/年,而且可以原价续费两年,截止日期为2026年3月,所以我还是剁手了。 借着这次机会写一部分建…

lv 14 字符设备读写操作实现 5

一、读操作实现 ssize_t xxx_read(struct file *filp, char __user *pbuf, size_t count, loff_t *ppos); 完成功能:读取设备产生的数据 参数:filp:指向open产生的struct file类型的对象,表示本次read对应的那次openpbuf&#xf…

分布式(7)

目录 31.基于Zookeeper如何实现分布式锁? 32.什么是ACID? 33.什么是分布式的XA协议? 34.什么是2PC? 35.什么是3PC? 31.基于Zookeeper如何实现分布式锁? 顺序节点 创建一个用于发号的节点“/test/lock…

Underactuated Robotics - 欠驱动机器人学

系列文章目录 DRAKE - 基于模型的机器人设计与验证 由丰田研究所支持的 C / Python 工具箱。 前言 © Russ Tedrake, 2023 注:这是麻省理工学院一门课程的工作笔记。它们将在 2023 年春季学期中不断更新。讲座视频可在 YouTube 上观看。 您也可以从这里下载…

应用在游戏机触摸屏中的触摸感应芯片

触屏游戏机的屏幕是由液晶屏和触控层组成的。触控层分为电容式触屏和电阻式触屏两种。电容式触屏是将悬空电极和屏幕玻璃上的电极组成静电场,当人体接近屏幕时,就会改变静电场分布,从而实现触摸的位置探测。而电阻式触屏则是利用玻璃上的两层电极之间通电形成一个电阻值,当手指…

【python入门】day19:学生管理系统需求分析、系统设计、主函数设计

需求分析 应具备功能—— 添加学生及成绩信息; 将学生信息保存到文件中; 修改和删除学生信息; 查询学生信息; 根据学生成绩进行排序; 统计学生的总分 系统设计 1.录入学生信息模块 2.查找 3.删除 4.修改 5.成绩排名…

数据分析求职-简历准备

简历在整个求职过程中的重要性不言而喻,今天咱们来聊求职过程中简历准备的那些事儿~ 1. 简历究竟有啥用 求职的流程简单说就是:网申->笔试->面试->offer 其中网申环节,简历100%决定了你的通过与否,这个点大家都知道。…

react 6种方式编写样式

在React中,编写样式主要有以下几种方式: 内联样式:直接在React组件中使用style属性来定义样式。这种方式比较适合定义动态的样式,因为它允许你将JavaScript表达式作为样式的值。 外部样式表:通过创建外部的CSS文件&am…

计算机Java项目|Springboot+vue 学生心理咨询评估系统

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、Python项目、前端项目、人工智能与大数据、简…

数据结构入门到入土——ArrayList与顺序表

目录 一,线性表 二,顺序表 1.接口实现 三,ArrayList简介 四,ArrayList使用 1.ArrayList的构造 2.ArrayList常见操作 3.ArrayList的遍历 4.ArrayList的扩容机制 五,ArrayLisit的具体使用 杨辉三角 一&#x…

linux 使用log4cpp记录项目日志

为什么要用log4cpp记录项目日志 在通常情况下,Linux/UNIX 每个程序在开始运行的时刻,都会打开 3 个已经打开的 stream. 分别用来输入,输出,打印错误信息。通常他们会被连接到用户终端。这 3 个句柄的类型为指向 FILE 的指针。可以…

【保研记录】2023年(24届)SE上岸经历

先开个坑,慢慢填~ 个人信息 学校:某双非 专业:软件工程 第四轮学科评估:无(对就是没有等级) 排名:1/400 竞赛/荣誉:国奖x2,省三好,大英国二,…

视频剪辑方法:一键批量转码,视频转GIF教程详解

在数字媒体时代,视频剪辑已经成为一项必备技能。无论是专业人士还是普通用户,都要对视频进行剪辑、转码和制作。但是视频剪辑并不简单,要掌握一定的技巧和知识。下面一起来看云炫AI智剪简单易学的视频剪辑方法:一键批量转码和视频…

案例093:基于微信小程序的南宁周边乡村游设计与实现

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

【MATLAB】【数字信号处理】线性卷积和抽样定理

已知有限长序列:xk1,2,1,1,0,-3, hk[1,-1,1] , 计算离散卷积和ykxk*h(k) 。 程序如下: function [t,x] My_conv(x1,x2,t1,t2,dt) %文件名与函数名对应 %自写的卷积函数 x conv(x1,x2)*dt; t0 t1(1) t2(1); L length(x1) length(x2)-2; t t0:dt…

thinkphp6入门(14)-- 多关联模型查询

背景: 有3个数据表,一个User表,一个Cloth表,一个Shoe表。 Cloth表和Shoe表分别和User表通过user_id关联。 thinkphp 6中如何通过模型查询所有用户,其中包括每个用户的cloth和shoe。 多关联模型查询: 1.…