RxJS mergeMap 与 switchMap 的详解及应用
在 RxJS 中,我们经常会用到 mergeMap 和 switchMap 这两个操作符,它们分别用于将一个 Observable 转换为另一个 Observable。本文将深入研究 mergeMap 和 switchMap 的特点、用法和示例,并帮助开发者更好地理解和应用它们。
mergeMap 的特点和用法
mergeMap 的作用是将发射的项转换为 Observable,并将这些 Observable 打平为单个 Observable 流。在每个新项目到达时,会启动一个新的 Observable 流,之前的流会被继续跟踪。
例如,我们有一个 Observable 流,代表了用户选择一个城市后,系统将返回该城市的所有景点信息。那我们可以通过 mergeMap 操作符,将景点信息的 Observable 流打平到一个单一的流。
const cities$ = from(['Beijing', 'Shanghai', 'Guangzhou']); const cityPoints$ = cities$.pipe( mergeMap(city => getCityPoints(city)), );
上面代码中的 getCityPoints 函数会接收一个城市名作为参数,并返回一个 Observable,该 Observable 会发射该城市的所有景点信息。
mergeMap 通常比 flatMap 更好,因为它在 Observable 流中保持了项目的顺序,而其它的并发操作符(如 concatMap 和 switchMap)可能会重排序。
switchMap 的特点和用法
switchMap 与 mergeMap 相似,也是将一个 Observable 转换为另一个 Observable,但它会同时处理多个 Observable,每当要处理新的 Observable 时,会直接取消订阅之前未完成的 Observable。
通常用于在输入框中输入某个关键字后,希望取消之前的搜索请求并发起新的搜索请求。
const searchInput = document.getElementById('search-input'); const searchResults$ = fromEvent(searchInput, 'input').pipe( map(e => e.target.value), debounceTime(500), distinctUntilChanged(), switchMap(query => search(query)), );
上述代码中,我们会从一个输入框的事件流中获取到输入文本的时时变化,然后利用 debounceTime 函数和 distinctUntilChanged 函数对搜索进行防抖和去重操作。最后,我们通过 switchMap 函数将其中断的搜索请求取消,只保留最新的一次搜索请求。
mergeMap 和 switchMap 两者的对比
mergeMap 和 switchMap 都是一种将一个 Observable 转换成另一个 Observable 的操作符,但它们之间有一些区别:
mergeMap 将源 Observable 中的每个项目映射到一个 Observable,并将这些 Observable 合并成单个 Observable。另一方面,switchMap 将每个源 Observable 项目映射到 Observable,但只发出由最新映射 Observable 发出的值,它会自动取消之前的 Observable 订阅,始终保持最新的 Observable。
switchMap 可以用来取消悬挂的请求或 AJAX 请求。
mergeMap 是按真正的发生顺序处理源 Observable 和映射的 Observable。而 switchMap 切换到新的 Observable 后,旧 Observable 将被取消。
总结
本文介绍了 RxJS 中的 mergeMap 与 switchMap 操作符的特点和用法,并通过相关示例帮助开发者更好地理解和应用这两个操作符。需要注意的是,在使用这两个操作时,开发者需要根据具体情况灵活选择,以达到最佳的效果。
示例代码
代码片段:https://codesandbox.io/s/rxjs-mergemap-and-switchmap-foh4d
HTML 代码:
-- -------------------- ---- ------- --------- ----- ----- ---------- ------ ----------- -------- --- ----------------- ------- ------ ----- -------- ------ ---- -- - ----- ----- ------ ----------- --------------- -- --------- ------ ----- --- ---------------------- ------ ------- -------------------------------------------------------------- ------- --------------------------- ------- -------
JavaScript 代码:
-- -------------------- ---- ------- ----- - --------- --------- - - ----- ----- - --------- --------- - - --------------- ----- --------- - -------------------------------------- ----- ---------- - --------------------------------------- --- - ---- ------- ------ ------ -- ---- ---- -- -------- ------------------- - ----- ------ - ---------------------------- ---- -- -- ----- ------ ----- - -- -- --------- ----- --------------------- - ---- ---- ------ ---------------------- - ----------- ------------ -- - -- ------------------------- - --- --- -- - ------ ----------------------- -------------- ---------- - ------ ----------------------------------- --- -- - --- - ---- ------ -- -- --- --- ----- ----- -- -------------------- -------- ------ ---------- -- ----------------------------------- -- --- ---- -- ----- ---- ------ -- -- ---------- ----- ------------------ ---------------- --- -- ---- ------- --- ------ --- ----- ------- -- -- -------------- -- - -------------------- - ------------------------ ------ ----------- -- -- -- -- ------ ----- -- ----- ----- ------------- -- ------------------------------ - --------------- -- - ----- -- - ----------------------------- ----- - - ---------------------------- ----------- - ---------- ------ - ---------- ------------------ --------------------------- ---
效果图:
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6471c56c968c7c53b0fa3369