switchMap,concatMap,mergeMap,exhaustMap 对比

99 阅读2分钟

在RxJS中,switchMapconcatMapmergeMapexhaustMap都是高阶映射操作符(Higher-Order Mapping Operators),用于将一个Observable的值映射成另一个Observable(内部Observable),然后订阅它。它们的差异在于如何处理内部Observable的订阅和取消订阅,尤其是在源Observable发出新值而内部Observable尚未完成时。

switchMap

  • 行为:当源 Observable 发出新值时,立即取消上一个未完成的内部 Observable,并切换到新的内部 Observable。
  • 适用场景:只关心最新请求的结果(如用户连续输入搜索词时,自动取消未完成的旧请求,只保留最新请求的结果)。

image-20250801150202217.png

concatMap

  • 行为:严格按顺序执行内部 Observable。前一个内部 Observable 未完成时,新值会被缓存,直到前一个完成后再按顺序执行。
  • 适用场景:需要严格保证顺序的任务(如文件上传队列、数据库顺序写入)

image-20250801150407733.png

mergeMap

  • 行为同时启动所有内部 Observable,允许并发执行(可通过参数 concurrent 限制并发数)。不保证完成顺序。
  • 适用场景:允许并发的独立任务(如批量下载文件)。

image-20250801150535525.png

exhaustMap

  • 行为:当内部 Observable 未完成时,忽略所有新值。只有当前内部 Observable 完成后,才接受下一个新值。
  • 适用场景:如按钮防止重复提交

image-20250801150601094.png

总结

  1. 需要最新结果switchMap
  2. 需严格顺序执行concatMap
  3. 允许并发且顺序无关mergeMap
  4. 需忽略重复请求exhaustMap

理解这些差异能有效避免竞态条件和资源浪费,根据场景选择正确的操作符是 RxJS 高效应用的关键。选择正确的操作符,本质是根据业务场景制定异步操作的冲突解决策略,从而保证数据一致性和用户体验。