map、mergeMap和switchMap是RxJS中的三大算子,在SAPSpartacus的开发中有着广泛的使用场景。mapmap是Observables上最常见的运算符。它的工作方式比较像数组中的地图。map获取从Observable发出的每个值,对其执行操作并返回一个Observable(因此Observable链可以继续)。将其视为将采用原始值和投影的函数。此函数将投影应用于所述值并返回转换后的值。让我们举个例子。假设我们有一个Observable数组。这个数组是Person的集合。一个对象代表每个人,每个人都有自己的名字和最喜欢的角色。我们只对获取所有角色的列表感兴趣。从'rxjs'导入{of};从'rxjs/operators'导入{map};constobservable=of([{name:"Parwinder",character:"Calcifer"},{name:"Laure",character:"炼金术士"},{name:"Eliu",character:"X-Men"},{名字:“罗伯特”,角色:“林克”}]);observable.pipe(map(arr=>arr.map(person=>person.character))//遍历对象并返回字符)。subscribe(char=>console.log(char)//["Calcifer","Alchemist","X-Men","Link"]);mergeMapmergeMap是Observablemap和mege的组合。在实际项目中,经常需要map生成多个Observable。例如,现在我有一组角色,对于每个角色,我想进行一次后端调用并获取一些信息。请参见以下示例:从'rxjs'导入{of,from};从'rxjs/operators'导入{map};constdummyApi=(character)=>{//假的api调用函数returnof(`APIresponseforcharacter:${character}`).pipe(delay(1000)//假的api需要1秒);}from(["Calcifer","Alchemist","X-Men","Link"])//我需要获取信息的角色for.pipe(map(arr=>dummyApi(arr))//生成4个新的Observables)。subscribe(//订阅Observable(outer)of4Observables(inner)data=>data.subscribe(i=>console.log(i))//订阅innerObservables)dummyApi是真实项目中的典型例子:输入a某个关键字,返回关键字对应的详细信息,包裹在一个Observable对象中。也就是说,地图投影的输出是一个Observable,而不是一个普通的对象,所以上面的代码写了丑陋的嵌套订阅来获取实际值。使用mergeMap后,这个算子可以自动扁平化map返回的Observable。使用地图时丑陋的双订阅调用消失了。从'rxjs'导入{of,from};从'rxjs/operators'导入{mergeMap};constdummyApi=(character)=>{returnof(`APIresponseforcharacter:${character}`)..pipe(delay(1000));}from(["Calcifer","Alchemist","X-Men","Link"]).pipe(mergeMap(arr=>dummyApi(arr))//获取4个Observable作为API响应并合并它们).subscribe(//我们订阅一个映射和合并的Observable数据=>console.log(data))switchMapswitchMap与mergeMap做同样的事情,但有一点不同。switchMap会订阅外层Observable中的所有内层Observable,但不会合并内层Observable。它改为切换到最新的Observable并将其传递到链中。它仍然提供一个Observable作为输出,不是通过合并,而是通过只从最新的Observable发出结果的想法。对于我们的最后一个例子,如果我们使用switchMap,我们将只会从最后一个Observable获得结果。从'rxjs'导入{of,from};从'rxjs/operators'导入{switchMap,delay};constdummyApi=(character)=>{returnof(`APIresponseforcharacter:${character}`).pipe(delay(1000));}from(["Calcifer","Alchemist","X-Men","Link"]).pipe(switchMap(arr=>dummyApi(arr))).subscribe(data=>console.log(data)//APIresponseforcharacter:Link)有些场景是switchMap擅长的,比如所谓的打字头。想象这样一个场景:UI上有一个输入框,我们在里面发送给它返回搜索结果。如果用户要键入Chase,请开始键入C,并触发API调用。然后客户继续输入h,我们又要为Ch调用后台API。至此,我们之前对C的API调用就没有用了。我们应该取消之前的Observable,订阅Ch对应的Observable。更一般地,我们需要切换到最新的Observable.import{of,from}from'rxjs';import{switchMap,delay}from'rxjs/operators';constdummyApi=(character)=>{returnof(`Search关键字的结果:${character}`).pipe(delay(1000));}from(["C","Ch","Cha","Chas","Chase"])//模拟按键输入textfield.pipe(switchMap(arr=>dummyApi(arr))).subscribe(data=>console.log(data)//关键字搜索结果:Chase)
