「这是我参与2022首次更文挑战的第30天,活动详情查看:2022首次更文挑战」
tap
tap 是一个非常基础的操作符,它的作用就是执行副作用,虽然我们可以在执行 map 之类的操作同时添加一些副作用操作,但是这样实际上不是最佳实践,这些操作会造成函数不纯。而 tap 是专门用来执行副作用的操作符,最常用的就是打印日志:
of(1, 2, 3).pipe(tap(console.log));
弹珠图:
finalize
finalize 实现的是一个类似析构函数的效果,我们可以添加一个回调,当流正常或异常结束,或者流被取消订阅时 finalize 回调函数会触发:
interval(1000).pipe(
take(3),
finalize(() => console.log('end'))
).subscribe(console.log);
// 0
// 1
// 2
// end
delay、delayWhen
给流添加一个延迟,delay 可以设置延长固定的时间或者延迟到特定的时间点,delayWhen 接收返回 Observable 的函数为参数,由 Observable 决定延迟时间,举个例子:
fromEvent(document, 'click').pipe(delay(1000)).subscribe(x => console.log(x));
每点击一次会在一秒后打印内容。
delay 的弹珠图:
delayWhen 的弹珠图:
materialize、dematerialize
materialize 可以将流内容封装为 Notification 对象,dematerialize 是其反向操作,可以将 Notification 还原为普通的数据内容,举一个 materialize 的例子:
const letters = of('a', 'b', 13, 'd');
const upperCase = letters.pipe(map(x => x.toUpperCase()));
const materialized = upperCase.pipe(materialize());
materialized.subscribe(x => console.log(x));
// - Notification {kind: "N", value: "A", error: undefined, hasValue: true}
// - Notification {kind: "N", value: "B", error: undefined, hasValue: true}
// - Notification {kind: "E", value: undefined, error: TypeError:
// x.toUpperCase is not a function at MapSubscriber.letters.map.x
// [as project] (<http://1>…, hasValue: false}
materialize 的弹珠图:
dematerialize 的弹珠图:
timeout、timeoutWith
timeout 是超时,效果为如果在给定的时间内没有产生新值,就直接抛出错误,当出错时可以通过 with 来切换至其他流处理。timeoutWith 在参数上与 timeout 不同,举个例子:
const slow$ = interval(900);
const fast$ = interval(500);
slow$.pipe(
timeout({
each: 1000,
with: () => fast$,
})
)
.subscribe(console.log)
弹珠图:
timeInterval
获取当前值与上一次值的时间间隔信息,
interval(1000).pipe(timeInterval()).subscribe(v => console.log(v));
// {value: 0, interval: 1000}
// {value: 1, interval: 1000}
// {value: 2, interval: 1000}
// ...
弹珠图:
timestamp
为流的每一项添加发出的时间戳,给每个数据添加一个发出的时间标识,看一下效果:
fromEvent(document, 'click').pipe(timestamp()).subscribe(console.log);
添加了 timestamp 后,每次打印的内容会变为 { value: xxx, timestamp: number } 格式。
弹珠图:
toArray
收集流中的全部数据,将其转化为数组发出,举个例子:
interval(1000).pipe(
take(3),
toArray()
).subscribe(v => console.log(v));
// [0, 1, 2]
弹珠图描述也特别简单:
曾经还有一个 toPromise 方法,现在已经废弃了,相关的场景可以使用 lastValueFrom 或 firstValueFrom 来实现,具体可以参考这篇文章。
除了上面的这些,还有 observeOn 和 subscribeOn 两个工具操作符,这两个与调度器的使用有关,这里不展开介绍了,工具操作符这里就了解这么多。