实践是知识的母亲,知识是生活的明灯。这篇文章主要讲述5 张弹珠图彻底弄清 RxJS 的拉平策略:mergeMapswitchMapconcatMapexhaustMap相关的知识,希望能为你提供帮助。
map 操作想必大家一定不陌生:
constof= Rx;
constmap= 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 呢 ?
constof= Rx;
constmap= 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?
? ,则可以得值:constof= Rx;
constmap= 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? 操作符;
代码如下:
constof= Rx;
constmergeMap = 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?
constof,interval = Rx;
constmergeMap,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?
constof,interval = Rx;
constswitchMap,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?
constof,interval = Rx;
constconcatMap ,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?
constof,interval = Rx;
constexhaustMap ,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)】
推荐阅读
- Go 语言入门很简单(Go 中的作用域和变量隐藏)
- 扩展433兆赫射频发射模块的传输范围
- Flutter 专题101 何为 Flutter Elements (#yyds干货盘点#)
- #yyds干货盘点# Spring核心之控制反转(IOC)
- 路由基础之OSPF的监测和调试
- ThinkPHP上次和下载封装
- Cilium v1.10.6 安装部署
- 算法题每日一练---第36天(连续子数组的最大和)
- 云原生时代的搜索服务算力管理