RxJS高阶map使用问题:如何得到Observable<SearchResult[]>而非嵌套类型
问题根因
你代码的问题出在第一层使用了map操作符:map的作用是把上游发射的值做普通转换后直接往下传,而你在map的回调里返回的是combineLatest(searchByIDSearchResults$)生成的新Observable,map不会处理这个Observable的订阅逻辑,只会把它当成普通值往下游抛,所以最终得到的就是嵌套的Observable<Observable<SearchResult[]>>类型。
修复方案
把第一层的map替换为RxJS的高阶映射操作符即可,这类操作符会自动订阅内层的Observable,把内层发射的值直接打平传到下游,最终得到的就是你需要的Observable<SearchResult[]>类型。
搜索场景下推荐使用switchMap:当上游有新的值发射时,会自动取消前一次未完成的内层Observable请求,避免旧的搜索结果覆盖新的请求结果。
修改后的代码如下:
const observable$ = combineLatest([searchAPI$, searchByID$]) // Line 1 .pipe( // 把这里的map换成switchMap即可 switchMap(data => { let APISearchResult = data[0]; // 为SearchResult类型数组 const searchByIDRawData = data[1]; // 为Opportunity类型数组 // 为每个Opportunity类型元素创建对应的Search Result Observable数组 const searchByIDSearchResults$ = searchByIDRawData.map(s => this.CreateSearchResultItemFromOpportunity(s, keywordSearch)); // Line 7 return combineLatest(searchByIDSearchResults$) .pipe( map(searchResults => { return APISearchResult.concat(searchResults); // 合并APISearchResult与searchByIDSearchResults$的输出 }) ) })) return observable$;
如果你的业务场景有其他需求,可以按需替换为其他高阶映射操作符:
- 需严格按请求顺序返回结果,优先用
concatMap - 需并行处理所有内层请求、不取消未完成的旧请求,优先用
mergeMap - 仅需要处理第一个发射的请求、后续请求直接忽略,优先用
exhaustMap
内容的提问来源于stack exchange,提问作者taylorswiftfan
相关产品推荐
相关产品推荐

