RxJS 中的 mergeMap() 与 switchMap() 之间的区别
前言
使用 RxJS 是现代化 Web 应用程序开发中的一项重要技术。而 RxJS 中的 mergeMap() 与 switchMap() 作为两个变换操作符,具有一些相同的特性和用途,但也有比较明显的区别,本文将重点介绍它们之间的差异以及适用场景,帮助读者更好地理解优化自己的应用程序。
mergeMap()
mergeMap() 也称为 flatMap(),它的主要功能是将一个值映射为另一个可观察序列,并且将这些可观察序列合并成一个单一的可观察序列。举例来说,如果你有一些异步操作,并且每个异步操作都返回一个可观察序列,那么使用 mergeMap() 可以将这些可观察序列合并起来,并统一发射结果。下面是具体使用方式:
// javascriptcn.com 代码示例 import { of } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; const source = of('hello', 'world'); const example = source.pipe( mergeMap(val => of(`${val} RxJS!`)) ); example.subscribe(console.log); // 输出: // "hello RxJS!" // "world RxJS!"
对于单个值,mergeMap() 与 map() 是等价的操作符。但是对于返回 Observable 的函数,mergeMap() 将它们的结果合并成一个单一的流,而不是按顺序排列每个流的输出。这样可以更好地利用并行性并使异步代码更有效。
switchMap()
switchMap() 的主要功能是将一个值映射为另一个可观察序列,并关闭上一个可观察序列,只发出最新映射的可观察序列,并忽略之前的。如果有多个可观察序列仍在工作,则它们将被取消并清除。举例来说,假设我们有一个输入框,我们想要将用户的输入映射为 Ajax 请求并发出请求结果。下面是具体的使用方式:
// javascriptcn.com 代码示例 import { fromEvent } from 'rxjs'; import { switchMap } from 'rxjs/operators'; const search = document.getElementById('search'); const result = document.getElementById('result'); const search$ = fromEvent(search, 'keyup').pipe( switchMap(event => { const term = event.target.value; return searchWikipedia(term); }) ); search$.subscribe(data => { result.innerHTML = data; }); function searchWikipedia(term) { const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${term}&format=json&origin=*`; return fetch(url) .then(response => response.json()) .then(data => data.query.search[0].snippet); }
上述代码定义了一个名为 searchWikipedia() 的函数,它返回一个 Promise,该 Promise 解析为特定主题的 JSON 数据。在 search$ 中使用 switchMap() 操作符,可以映射事件并生成 Ajax 请求的 Observable。此后,在 Ajax 请求成功后,它会从 Observable 中发出请求结果,并设置到结果 Div 元素中。
总结
两者主要的区别在于,如果使用 mergeMap(),则所有结果都可以按任意顺序到达 (例如从不同的 HTTP 请求中),但是使用 switchMap(),只会发射来自最近的可观察序列,并且会在新值到达时立即取消它之前的 Observable,以确保异步操作始终是最新的。也就是说,如果我们只关心最近的异步操作,那么就应该使用 switchMap();反之,如果我们希望同时处理多个异步操作的数据,请使用 mergeMap()。
建议
可以根据业务需求,结合实际代码场景,更灵活的选择 mergeMap() 或 switchMap() 操作符。使用 RxJS 更好的代码组织可以提高开发工作效率,减少不必要的耗时。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/652b7b417d4982a6ebd5a52e