RxJS 是一个开源的响应式编程库,可以在前端中使用,帮助 JavaScript 开发者处理异步操作和事件流,并且不需要使用回调函数和 Promise。RxJS 中有很多重要的操作符,其中 switchMap 和 mergeMap 是两个常用的变换操作符。
目录
- RxJS 概述
- switchMap 操作符
- 使用案例
- 操作符内部如何工作
- switchMap 和其他操作符的区别
- mergeMap 操作符
- 使用案例
- 操作符内部如何工作
- mergeMap 和其他操作符的区别
- 总结
1. RxJS 概述
RxJS 是 ReactivX 库的一部分,它是用 TypeScript 编写的,而且可以在前端中使用。它能够通过交互式查询方式处理异步事件流。RxJS 相当于是对事件流进行函数式编程处理,它能够使想要达成的某个需求非常简单和容易实现。
RxJS 主要包含以下四个核心组件:
- Observables:表示一个异步的数据流的集合。
- Operators:一些像 RxJS.Observable.prototype.map, RxJS.Observable.prototype.filter 等等的纯函数,可以用来处理 Observables 并生成新的 Observables。
- Schedulers:控制如何执行和调度异步工作。
- Subjects:是一个特殊类型的 Observable,有独特的性质使得它们更适合多播值。
在本文中,我们将重点介绍 Observables 的两个操作符 switchMap 和 mergeMap。
2. switchMap 操作符
switchMap 操作符将 Observable 中的每一个值映射成一个新的 Observable,然后将所有生成的 Observables 加入到一个新的 Observable 中,并立即启动最新的 Observable,丢弃前一个 Observable。
使用案例
下面的代码演示了 switchMap 操作符的使用:
import { interval, fromEvent } from 'rxjs'; import { switchMap } from 'rxjs/operators'; const button = document.querySelector('#btn'); const clicks$ = fromEvent(button, 'click'); const data$ = clicks$.pipe( switchMap(() => interval(1000)) ); data$.subscribe(result => console.log(result));
在上面的代码中,我们创建了一个按钮的点击事件流,每当点击按钮时,数据流将发出 click 事件。然后,我们使用 switchMap 操作符来将每个 click 事件转换成一个新的 interval Observable,发射值的间隔为 1 秒钟。订阅了新生成的 Observable,然后通过 subscribe 方法将发射的值输出到控制台。
操作符内部如何工作
switchMap 操作符首先订阅源 Observable(clicks$),一旦一个新的值(即 click 事件)发生,那么它就把这个值传递给一个函数(本例中是 () => interval(1000))。这个函数必须返回一个 Observable。
因为 switchMap 操作符会停止之前的 Observable,因此如果之前的 Observable 还有未完成的操作时调用这个函数,那么这个操作将不会被完成。在使用 switchMap 操作符的时候还需要特别注意嵌套问题的存在。
switchMap 和其他操作符的区别
switchMap 和其他类似的操作符(如 map 和 mergeMap)的主要区别在于:switchMap 只会在发生新值时才会生成一个新的 Observable 并解绑旧的 Observable,而且在新的 Observable 的发射之前不会发射值。
3. mergeMap 操作符
mergeMap 操作符将源 Observable 中的每一个值映射成一个新的 Observable,然后将所有生成的 Observables 加入到一个新的 Observable 中,可以同时启动多个 Observable。每个元素都可以映射到任意数量的 Observable 上,这些 Observables 可以在单个并发池中同时激活。这意味着 mergeMap 等待所有的 Observable 发出的值。最后,把所有产生的值按顺序排列到一起,并且将它们发射给下一个 Operator 或者输出给使用者。
使用案例
下面的代码演示了使用 mergeMap 操作符:
import { fromEvent } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; const button = document.querySelector('#btn'); const clicks$ = fromEvent(button, 'click'); const data$ = clicks$.pipe( mergeMap(() => interval(1000)) ); data$.subscribe(result => console.log(result));
在上述示例中,我们创建点击事件流,每当点击按钮时,数据流将发出 click 事件。接下来我们使用 mergeMap 操作符将每个 click 事件转换成一个新的 interval Observable,该 Observable 以 1 秒的间隔发出值。在此之后,通过调用 subscribe 订阅新生成的 Observable 并将发出的值输出到控制台。
操作符内部如何工作
mergeMap 操作符会订阅源 Observable,并等待源 Observable 产生可观察对象。每当源 Observable 产生一个值时,mergeMap 操作符会为每个值创建一个新的 Observable,然后合并所有的 Observable 并发出所有的值。注意,当 mergeMap 操作符创建这些 Observable 时,每个 Observable 都可以映射到不同的值。
mergeMap 与其他操作符的区别
mergeMap 操作符与 switchMap 操作符的区别在于,mergeMap 操作符会同时管道化多个 Observable。这包括同步和异步 Observables,因此所有发出的值都可以在任意时间产生。而 switchMap 操作符不能同时处理两个 Observable。
4. 总结
本文主要描述了 RxJS 中两个重要的变换操作符,即 switchMap 和 mergeMap。它们之间的区别主要在于处理多个 Observable 时的方式,switchMap 只会处理最新的 Observable,而 mergeMap 会同时管道化多个 Observable。
在开发过程中,我们应该先确定使用何种操作符才能更好地解决我们的问题。在某些情况下,switchMap 操作符的设计能够很好地进行数据流的控制,并且非常有用。在其他情况下,mergeMap 操作符则能够更好地解决问题。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6594c686eb4cecbf2d90b9ba