RxJS 中的 switchMap、mergeMap 和 concatMap 操作符
在 RxJS 中,map 操作符常常被用来对 observable 数据流中的每个数据进行变换操作。然而,在某些情况下,我们需要对 observable 数据流中的数据进行过滤、映射以及合并等操作。这时,就需要用到 switchMap、mergeMap 和 concatMap 这三个操作符。
switchMap 操作符
switchMap 操作符是 RxJS 中一个十分强大的操作符,它可以对 observable 数据流中发出的每一个数据项进行映射变换,并且可以将这些映射结果转换成新的 Observable。同时这个新的 Observable 可以暂停之前的 Observable,也可以订阅到另一个 Observable。当一个新的 Observable 被订阅时,原来的 Observable 就会被取消,同时之前所有的未完成任务也都会被取消。下面是 switchMap 操作符的示例代码:
// javascriptcn.com 代码示例 import { fromEvent } from 'rxjs'; import { switchMap, map } from 'rxjs/operators'; const searchBox = document.getElementById('search-box'); const searchResult = fromEvent(searchBox, 'input').pipe( map((e: KeyboardEvent) => e.target.value), switchMap((value: string) => { return ajax('/api/search?q=' + value); }) ); searchResult.subscribe( res => console.log(res), err => console.log(err), () => console.log('complete') );
在上面的代码中,我们在搜索框输入内容时,利用 fromEvent 将事件转换成 Observable。然后对每个输入框的值进行了 map 变换,最后用 switchMap 操作符将变换后的 Observable 转换成了 ajax 请求 Observable,并且完成了订阅。
mergeMap 操作符
mergeMap 操作符与 switchMap 操作符类似,也是用于映射每个 Observable 数据流中的数据项,并且将映射结果转换成新的 Observable。mergeMap 操作符的不同之处在于,它不会取消正在进行的旧的 Observable,而是将与新 Observable 同时进行。下面是 mergeMap 操作符的示例代码:
// javascriptcn.com 代码示例 import { fromEvent } from 'rxjs'; import { mergeMap, map } from 'rxjs/operators'; const searchBox = document.getElementById('search-box'); const searchResult = fromEvent(searchBox, 'input').pipe( map((e: KeyboardEvent) => e.target.value), mergeMap((value: string) => { return ajax('/api/search?q=' + value); }) ); searchResult.subscribe( res => console.log(res), err => console.log(err), () => console.log('complete') );
在上面的代码中,我们使用 mergeMap 操作符将输入框的值与 ajax 请求 Observable 进行了合并,可以看到,不同于 switchMap 操作符,我们可以同时看到两个不同请求的结果。
concatMap 操作符
concatMap 操作符用于将多个 Observable 按顺序进行连接,将 Observable 中的每一个值按顺序进行处理。在某些情况下,我们需要确保 Observable 中的值按照顺序进行处理,这时就需要用到 concatMap 操作符。下面是 concatMap 操作符的示例代码:
// javascriptcn.com 代码示例 import { fromEvent, of } from 'rxjs'; import { concatMap, map, delay } from 'rxjs/operators'; const searchBox = document.getElementById('search-box'); const searchResult = fromEvent(searchBox, 'input').pipe( map((e: KeyboardEvent) => e.target.value), concatMap((value: string) => { return of('searching for ' + value).pipe( delay(1000), map((search: string) => { return 'result for ' + search; }) ); }) ); searchResult.subscribe( res => console.log(res), err => console.log(err), () => console.log('complete') );
在上面的代码中,我们利用 of 操作符将每个输入框值转化成新的 Observable,然后用 concatMap 操作符将这些 Observable 进行连接,并且利用 delay 操作模拟网络请求。可以看到,输出结果按照顺序依次处理。
总结
在 RxJS 中,我们使用 switchMap、mergeMap 和 concatMap 操作符来处理 Observable 数据流中的数据项。它们各自具有各自的特性,可以帮助我们完成各种不同的任务。在使用时,我们需要根据具体的业务场景来选择不同的操作符。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6538f5727d4982a6eb224c79