如何在RxJS的map操作符中使用flatMap返回的多响应执行不同函数?
解决RxJS flatMap后链式执行多操作的问题
我来帮你理清这个问题,其实你已经找对方向啦,只是对操作符的数据流传递有点小困惑~
你的期望代码其实是可行的
首先,你写的这段期望代码本身是可以正常工作的:
flatMap(someResponse => combineLatest([ this.locator.function(someResponse, variable2), this.function1(someResponse), this.locator.function2(someResponse, variable3) ])), map(([response1, response2, response3]) => { this.function3(response1, response2); this.function4(response3); })
只要combineLatest里的三个Observable都能正常发出至少一个值,map操作符就能接收到包含三个响应的数组,然后你可以在这个map里直接调用function3和function4来处理对应的结果。
为什么加额外map会出问题?
你提到尝试添加另一个map却只能拿到前一个map的响应,这是因为map操作符会把当前函数的返回值传递给下一个操作符。如果你的第一个map没有返回任何数据(或者返回了undefined),那后续的map自然拿不到原始的三个响应。
如果确实需要拆分成多个map来分步处理,你需要把需要的数据传递下去,比如:
flatMap(someResponse => combineLatest([ this.locator.function(someResponse, variable2), this.function1(someResponse), this.locator.function2(someResponse, variable3) ])), // 第一个map处理function3,并把需要的数据传递下去 map(([response1, response2, response3]) => { this.function3(response1, response2); return { response3, response1, response2 }; // 返回后续需要的数据 }), // 第二个map处理function4 map(data => { this.function4(data.response3); // 如果不需要继续传递数据流,可以不返回值,或者返回最终结果 })
不过如果只是执行副作用操作(比如调用函数处理数据,不需要返回新的数据流),一个map就足够了,没必要拆分。
快速理清你提到的几个操作符差异
你提到对switchMap、concatMap等不太熟悉,这里简单给你区分下:
flatMap:是mergeMap的别名,会同时订阅内部所有Observable,按值发出的顺序传递结果,适合并行处理多个请求的场景。switchMap:每当新的Observable发出时,会立即取消之前的订阅,适合搜索输入这类需要丢弃旧请求的场景。concatMap:会按顺序订阅内部Observable,必须等前一个Observable完成后才会订阅下一个,适合需要保证执行顺序的场景。exhaustMap:会忽略新的Observable请求,直到当前正在处理的Observable完成,适合避免重复提交按钮这类场景。
补充:如果combineLatest没触发怎么办?
如果发现combineLatest没有触发,大概率是因为其中某个Observable从未发出值。这时候可以根据你的需求替换成:
forkJoin:适合所有Observable都是一次性请求(会完成)的场景,只有当所有Observable都完成后才会发出包含所有结果的数组。zip:会按顺序配对多个Observable发出的值,比如第一个Observable的第n个值和第二个Observable的第n个值配对,适合需要严格按顺序对应结果的场景。
内容的提问来源于stack exchange,提问作者Sojimanatsu
相关产品推荐
相关产品推荐

