You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJS exhaustMap未按预期运行,第二个投影Observable被忽略问题

问题原因分析

exhaustMap的核心工作逻辑是:只要当前存在尚未完成的投影Observable,所有在这期间由源Observable发射的新值都会被直接丢弃,不会生成对应的投影Observable,直到当前的投影Observable完全结束后,才会响应后续源发射的新值。

你的代码中,源Observable是from(['a','b']),它是同步发射值的,会在代码执行到pipe的瞬间立刻连续发射'a'和'b'两个值:

  • 第一个值'a'发射时,exhaustMap还没有正在处理的投影Observable,所以正常生成对应的getData('a')投影Observable并开始执行
  • 紧接着源立刻发射了第二个值'b',此时exhaustMap正在处理'a'对应的投影Observable,所以'b'这个值会被直接丢弃,根本不会生成对应的getData('b')投影Observable,和你给getData('b')设置的7秒延迟没有任何关系。
预期效果实现方案

如果你需要按顺序执行所有源值对应的投影Observable,上一个投影Observable完成后再执行下一个,应该使用concatMap操作符替代exhaustMap,修改后的代码如下:

import { from } from 'rxjs'; 
import { interval } from 'rxjs';
import { take } from 'rxjs/operators';
import { map, concatMap, delay } from 'rxjs/operators';

const getData = (param) => {
  if (param == 'a') {
    return interval(1000).pipe(
      map(val => param + '-' + val.toString()),
      take(4),
      delay(1000)
    )
  }
  else if (param == 'b') {
    return interval(1000).pipe(
      map(val => param + '-' + val.toString()),
      take(4),
      delay(7000)
    )
  }
}

// 使用concatMap按顺序执行所有投影Observable
from(['a','b']).pipe(
  concatMap(param => getData(param))
).subscribe(val => console.log(val));

修改后代码会先输出a-0到a-3,等待7秒后继续输出b-0到b-3,符合你预期的执行效果。

补充说明

exhaustMap适用的场景是需要忽略前一次请求未完成时触发的重复请求,比如用户频繁点击提交按钮时,只响应第一次点击,直到第一次请求完成前的所有点击都直接忽略,和你当前需要按顺序处理所有请求的场景不匹配。

内容的提问来源于stack exchange,提问作者mkedwards

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 14:57:03