5 张弹珠图彻底弄清 RxJS 的拉平策略:mergeMapswitchMapconcatMapexhaustMap
Posted 掘金安东尼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5 张弹珠图彻底弄清 RxJS 的拉平策略:mergeMapswitchMapconcatMapexhaustMap相关的知识,希望对你有一定的参考价值。
map 操作想必大家一定不陌生:
const of = Rx;
const map = RxOperators;
const namesObservable = of(A, B);
namesObservable.pipe(
map(name => `map $name`)
)
namesObservable .subscribe(result => console.log(`$result`))
// map A
// map B
很直观,因为 map 映射的是“值”,所以足够简单~
但是,如果说,map 映射的是 observable 呢 ?
const of = Rx;
const map = RxOperators;
const namesObservable = of(A, B);
const http =(name)=>
return of(`$name 1`,`$name 2`);
namesObservable.pipe(
map(name => http(name))
)
namesObservable.subscribe(result => console.log(`$result`))
// 则会得到两个 observable 对象
// ****observable ..
// observable ..
结果发现,最终得到的仍是 observable;在 https://rxviz.com/ 的弹珠图中,可以看到:
observable 由最初的 1 个,变成了 2 个(圆圈就是 observable),数据仍在里面没有被订阅解析出来。
虽然,我们可以用粗暴的方法,在订阅 .subscribe
里面再次调用订阅 .subscribe
,则可以得值:
const of = Rx;
const map = RxOperators;
const namesObservable = of(A, B);
const http =(name)=>
return of(`$name 1`,`$name 2`);
namesObservable.pipe(
map(name => http(name))
)
namesObservable .subscribe(resultObservable =>
resultObservable.subscribe(result => console.log(`$result`) )
)
// A1
// A2
// B1
// B2
但是,这样包裹写法注定是不优雅的,所以,为了解决这个差异,RxJS 引入了 —— Flattening(扁平化)策略!!
我们可以借助 flatMap 操作符,则能得到同样的解析值的效果~ flatMap 其实也就是我们熟知的 mergeMap 操作符;
代码如下:
const of = Rx;
const mergeMap = RxOperators;
const namesObservable = of(A, B);
const http =(name)=>
return of(`$name 1`,`$name 2`);
namesObservable.pipe(
mergeMap(name => http(name))
)
namesObservable.subscribe(result => console.log(`$result`))
// A1
// A2
// B1
// B2
更进一步,沿着这种偏平化策略思路,除了 mergeMap,RxJS 又引入了 switchMap、concatMap 和 exhaustMap,它们能够提供不同种类的拉平策略。
我们借助 https://rxviz.com/ 的弹珠图,一眼便能看到它们的差异:
我们设置一个定时器,每一秒都发出一个 observable,一共发 3 次,来看下分别得值;
- mergeMap
const of,interval = Rx;
const mergeMap,take,map = RxOperators;
const namesObservable = of(A, B);
const http =(name)=>
return interval(1000)
.pipe(
take(3),
map(()=>of(`$name 1`,`$name 2`))
)
namesObservable.pipe(
mergeMap(name => http(name))
)
- switchMap
const of,interval = Rx;
const switchMap,take,map = RxOperators;
const namesObservable = of(A, B);
const http =(name)=>
return interval(1000)
.pipe(
take(3),
map(()=>of(`$name 1`,`$name 2`))
)
namesObservable.pipe(
switchMap(name => http(name))
)
- concatMap
const of,interval = Rx;
const concatMap ,take,map = RxOperators;
const namesObservable = of(A, B);
const http =(name)=>
return interval(1000)
.pipe(
take(3),
map(()=>of(`$name 1`,`$name 2`))
)
namesObservable.pipe(
concatMap (name => http(name))
)
- exhaustMap
const of,interval = Rx;
const exhaustMap ,take,map = RxOperators;
const namesObservable = of(A, B);
const http =(name)=>
return interval(1000)
.pipe(
take(3),
map(()=>of(`$name 1`,`$name 2`))
)
namesObservable.pipe(
exhaustMap (name => http(name))
)
以上是关于5 张弹珠图彻底弄清 RxJS 的拉平策略:mergeMapswitchMapconcatMapexhaustMap的主要内容,如果未能解决你的问题,请参考以下文章