RxJS 中的 switchMap 和 concatMap 区别及使用场景

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