RxJS 是一种流式编程库,它提供了一些操作符来处理异步数据流。在 RxJS 中,switchMap 和 concatMap 是两个常用的操作符,它们都可以用来转换一个 Observable 对象,但它们的使用场景和效果有所不同。
switchMap
switchMap 操作符用于将一个 Observable 转换为另一个 Observable,并且只会发出最新的 Observable 中的值。当源 Observable 发出一个新值时,它会取消之前的 Observable 并订阅最新的 Observable。这个操作符可以用于解决如下场景:
- 在搜索框中输入关键字,触发搜索请求,但是如果用户连续输入多个关键字,前面的搜索请求会被取消,只会响应最后一个搜索请求的结果。
- 在某个状态下,需要发起一个异步请求,但是如果状态发生变化,就需要取消之前的请求,并重新发起新的请求。
下面是一个使用 switchMap 操作符的示例代码:
import { fromEvent } from 'rxjs'; import { switchMap } from 'rxjs/operators'; const input = document.querySelector('input'); fromEvent(input, 'input') .pipe( map(event => event.target.value), switchMap(keyword => search(keyword)) ) .subscribe(result => console.log(result)); function search(keyword: string) { return fetch(`https://api.github.com/search/repositories?q=${keyword}`) .then(response => response.json()) .then(data => data.items); }
在上面的代码中,我们使用 fromEvent 操作符创建了一个 Observable,它会在输入框中输入时发出一个值。然后使用 switchMap 操作符将输入框的值转换为一个搜索请求的 Observable。如果用户连续输入多个关键字,前面的搜索请求会被取消,只会响应最后一个搜索请求的结果。
concatMap
concatMap 操作符用于将一个 Observable 转换为另一个 Observable,并且按照顺序发出每个 Observable 中的值。当源 Observable 发出一个新值时,它会将这个值转换为一个新的 Observable,然后等待这个 Observable 完成后再发出下一个值。这个操作符可以用于解决如下场景:
- 有多个异步请求需要按照顺序执行,并且后面的请求依赖于前面请求的结果。
- 在某个状态下,需要发起一个异步请求,并等待请求完成后再执行下一个异步请求。
下面是一个使用 concatMap 操作符的示例代码:
import { from } from 'rxjs'; import { concatMap } from 'rxjs/operators'; const tasks = [ { name: 'Task 1', duration: 1000 }, { name: 'Task 2', duration: 2000 }, { name: 'Task 3', duration: 3000 }, ]; from(tasks) .pipe( concatMap(task => doTask(task)) ) .subscribe(() => console.log('All tasks are done')); function doTask(task: { name: string, duration: number }) { return new Promise(resolve => { setTimeout(() => { console.log(`Task ${task.name} is done`); resolve(); }, task.duration); }); }
在上面的代码中,我们使用 from 操作符创建了一个 Observable,它会按照顺序发出每个任务。然后使用 concatMap 操作符将每个任务转换为一个异步请求的 Observable,并等待请求完成后再执行下一个任务。
总结
switchMap 和 concatMap 都是 RxJS 中常用的操作符,它们可以用于将一个 Observable 转换为另一个 Observable,并且处理异步数据流。switchMap 可以用于取消之前的 Observable,并订阅最新的 Observable;而 concatMap 则可以按照顺序发出每个 Observable 中的值。在实际应用中,我们需要根据具体的场景选择合适的操作符来处理异步数据流。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c1378fadd4f0e0ffb26c98