一.引言
RxJS提供了很多操作符对数据流(Observable)进行操作控制。例如map,tap,skip,fiter等等,总会忘记他们的作用是什么,感觉自己是时候总结一下他们了。
二. 什么是操作符?
操作符是 Observable 类型上的方法,比如 .map(...)、.filter(...)等等。
操作符是函数,它基于当前的 Observable 创建一个新的 Observable。当操作符被调用时,它们不会改变已经存在的 Observable 实例。相反,它们返回一个新的 Observable ,它的 subscription 逻辑基于第一个 Observable 。
!何时会使用Observable类型
Observable通常使用在异步操作中。
异步操作又分为两种:
1 进行网络请求
2 setTimeout()指定在一定时间后调用的函数的这一类函数。
三.认识弹珠图
Marble diagrams (弹珠图): 更好的理解操作符是如何工作的图表。
弹珠的时间是从左到右流动的,是一条时间轴。
四.动手实践
操作符有着不同的用途,它们可作如下分类:创建、转换、过滤、组合、错误处理、工具,等等
1.创建
from 从一个数组、类数组对象、Promise、迭代器对象或者类 Observable 对象创建一个 Observable.几乎可以把任何东西都能转化为Observable.
2.转换 输入和输出数量相等,值不等。
map 操作符 它把每个源值传递给转化函数以获得相应的输出值。
举个栗子:
import { Component } from '@angular/core';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
example:Observable<number> = from([1, 2, 20, 50])
constructor() {
this.example.pipe(map(v => v*2)).subscribe(
data => console.log(data)
)
}
}
输出的结果:
:可以tap操作符做一下区分,tap操作符对源 Observable 上的每个发出值进行监听,做额外处理,但返回源相同的 Observable。输入和输出数量相等,值也相等。
3.过滤 输入数量大于等于输出数量相等。
举个例子:takeUntil
public takeUntil(notifier: Observable): Observable<T>
它发出源 Observable 的值,然后直到第二个 Observable (即 notifier )发出项,它便完成。
takeUntile一直过滤接受打出的Obervable值,知道接收到一个信号就停止就收了。
例子:
import { interval, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import {Component} from "@angular/core";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
value = interval(1000)
// 创建一个 Subject 作为停止条件
stop = new Subject();
// 创建一个 observable 每隔一秒发出一个值
source = interval(1000);
constructor() {
// 使用 takeUntil 操作符,当 stopCondition$ 发出值时停止接收 source$ 的值
const example = this.source.pipe(takeUntil(this.stop))
.subscribe(v => {
console.log(v)
})
setTimeout(() => {
console.log('Stop信号');
this.stop.next(1);
}, 5000);
}
}
4.组合
merge 将多个 observables 转换成单个 observable 。
public merge(other: ObservableInput, concurrent: number, scheduler: Scheduler): Observable
例子:
import { Component } from '@angular/core';
import {interval} from 'rxjs';
import { merge } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// 每2.5秒发出值
first = interval(2500);
// 每1秒发出值
second = interval(1000);
constructor() {
const example = this.first.pipe(merge(this.second))
example.subscribe(v => {
console.log(v)
})
}
}
输出结果:
输出:
- 条件操作符
find 只发出源 Observable 所发出的值中第一个满足条件的值。
例子
import { Component } from '@angular/core';
import {find, from} from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
first = from([1, 2, 3, 4, 5])
constructor() {
const example = this.first.pipe(find(v => v % 2 === 0))
example.subscribe(v => {
console.log(v)
})
}
}
输出的结果:
pipe操作符,在上面的例子中,每个操作符都被当做pipe()的参数了,pipe()函数的作用是什么呢?
pipe 用于组合多个操作符 ,以对数据流进行处理。可以将一系列操作符作为参数传递给 pipe 方法,这些操作符将 依次 对数据流进行处理。这里的依次很关键,也代表着pipe()中组合的这么几个操作符的执行顺序就是从开始一直到结束的,其中的数据会同流水线一般在各个操作符中进行传递。上一个操作符把数据处理好了,会自动地把这个处理好的数据送给下一个操作符接收,基于这个在上一步处理过的数据再进行进一步的加工,如此往复,直到执行到最后一个操作符为止。
例子:
import { Component } from '@angular/core';
import {filter, find, from, interval, Observable, takeUntil} from 'rxjs';
import { merge } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
first = from([1, 2, 3, 4, 5, 6]);
second = from([10, 20, 30, 40 ,50])
constructor() {
const example = this.first.pipe(merge(this.second), filter(v => v % 2 === 0))
example.subscribe(v => {
console.log(v)
})
}
}
输出的结果:
总结
Rxjs中的操作符能够优雅的处理异步事件以及数据流,值得我们学习, 最后希望这边文章能够给您带来帮助。如有说得不对的地方,还望指正,谢谢!
官方文档:https://cn.rx.js.org/manual/overview.html#h213
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。