RxJS 使用指南
Published by powerfulyang on Feb 27, 2022
switchMap
switchMap
和其他打平操作符的主要区别是它具有取消效果。在每次发出时,会取消前一个内部 observable (你所提供函数的结果) 的订阅,然后订阅一个新的 observable 。你可以通过短语切换成一个新的 observable来记忆它。
它能在像 typeaheads 这样的场景下完美使用,当有新的输入时便不再关心之前请求的响应结果。在内部 observable 长期存活可能会导致内存泄露的情况下,这也是一种安全的选择,例如,如果你使用 mergeMap 和 interval,并忘记正确处理内部订阅。记住,switchMap
同一时间只维护一个内部订阅。
不过要小心,在每个请求都需要完成的情况下,考虑写数据库,你可能要避免使用 switchMap
。如果源 observable 发出速度足够快的话,switchMap
可以取消请求。在这些场景中,mergeMap 是正确的选择。
1id$ = new Subject();
2
3price$ = id$.pipe(
4 switchMap(id => getPriceById(id))
5)
6
7// merge + map 很干净,省一个 subject
8isLoading$ = merge(
9 id$.pipe(mapTo(true)),
10 price$.pipe(mapTo(false))
11);
12
13getPriceById 需要返回一个 observable, unsubscribe 时 abort 请求即可。
14切商品直接 id$.next(newId), price$ 和 isLoading$ 会自动更新。
15上一次没完成的请求 switchMap 会自动 unsubscribe ,简直毫无负担。
mergeMap
- flatMap 是 mergeMap 的别名!
- 如果同一时间应该只有一个内部 subscription 是有效的,请尝试
switchMap
。 - 如果内部 observables 发送和订阅的顺序很重要,请尝试
concatMap
。
exhaustMap
返回的 Observable 基于应用一个函数来发送项,该函数提供给源 Observable 发出的每个项, 并返回一个(所谓的“内部”) Observable 。当它将源值投射成 Observable 时,输出 Observable 开始发出由投射的 Observable 发出的项。然而,如果前一个投射的 Observable 还未完成的话, 那么 exhaustMap 会忽略每个新投射的 Observable 。一旦完成,它将接受并打平下一个 内部 Observable ,然后重复此过程。
1只要没有当前活动的计时器,那么每次点击就会运行一个有限的计时器。
2var clicks = Rx.Observable.fromEvent(document, 'click');
3var result = clicks.exhaustMap((ev) => Rx.Observable.interval(1000).take(5));
4result.subscribe(x => console.log(x));
总结一下
rxjs 把 Promise 转成 Observable
在RxJS中,你可以使用from
操作符将Promise转换为Observable。这样,你就可以在RxJS的管道中使用Observable的各种操作符和方法。
以下是一个示例代码,展示了如何将Promise转换为Observable:
1import { from } from 'rxjs';
2
3const promise = new Promise((resolve, reject) => {
4 setTimeout(() => {
5 resolve('Promise resolved');
6 }, 2000);
7});
8
9const observable = from(promise);
10
11observable.subscribe({
12 next: value => console.log(value),
13 complete: () => console.log('Observable completed')
14});
在上面的示例中,我们创建了一个Promise,在2秒后解析(resolve)。然后,使用from
操作符将这个Promise转换为Observable。最后,我们订阅这个Observable,并在next
回调中打印解析的值。
当Promise解析后,Observable会发出相应的值,然后调用complete
回调来表示Observable完成。
这样,你就可以使用RxJS丰富的操作符和方法来处理异步操作了。
endWith 参数可以是 Observable ?
在RxJS中,endWith
操作符用于在Observable的末尾添加一个值或多个值。它并不接受Observable作为参数,而是接受一到多个参数值。
如果你想要在Observable的末尾添加一个Observable,你可以使用concat
操作符来实现。concat
操作符将两个或多个Observables连接起来,确保前一个Observable完成后才会订阅并发出下一个Observable的值。
以下是一个示例代码,演示了如何使用concat
操作符将Observable添加到另一个Observable的末尾:
1import { of, concat } from 'rxjs';
2
3const source1$ = of('Value 1', 'Value 2');
4const source2$ = of('Value 3', 'Value 4');
5
6const result$ = concat(source1$, source2$);
7
8result$.subscribe(value => console.log(value));
在上面的示例中,我们创建了两个Observable:source1$
和source2$
。然后,使用concat
操作符将它们连接起来,创建一个新的Observable result$
。
最后,我们订阅result$
并打印所有的值。运行上面的代码将会输出以下内容:
1Value 1
2Value 2
3Value 3
4Value 4
这样,你可以将一个Observable添加到另一个Observable的末尾,并确保它们的顺序被保持。