Typescript RxJS-将fromEvent与switchMap一起使用时的奇怪行为

Typescript RxJS-将fromEvent与switchMap一起使用时的奇怪行为,typescript,rxjs,Typescript,Rxjs,我有一个事件发射器,它可以相当快地发射事件,有时在同一个刻度中发射多个事件。当我从这个发射器创建一个可观察对象并使用switchMap时,我得到了一些奇怪的行为,n值进入switchMap,但只有1出来。下面是一些简化的代码: const e = new EventEmitter(); const s = fromEvent<ConfigurationUpdatePayload>( e, 'updated' ).pipe( take(4), map(() =>

我有一个事件发射器,它可以相当快地发射事件,有时在同一个刻度中发射多个事件。当我从这个发射器创建一个可观察对象并使用
switchMap
时,我得到了一些奇怪的行为,
n
值进入
switchMap
,但只有1出来。下面是一些简化的代码:

const e = new EventEmitter();


const s = fromEvent<ConfigurationUpdatePayload>(
  e,
  'updated'
).pipe(
  take(4),
  map(() => Math.random() > 0.3 ? 1 : 2),
  tap(v => console.log('pre', v)), //pre log
  switchMap(async (i) => [
    await Promise.resolve((i + 1) === 2),
    i
  ] as const),
  tap(v => console.log('post', v)), //post log
  filter(([f,]) => f),
  map(([, p]) => p)
);


s.subscribe(v => console.log('result', v));

for (let i = 0; i < 4; i++) {
  e.emit('updated', 1);
  // await new Promise(res => setTimeout(res, 1000)); - if I uncomment this it works
}
const e=neweventemitter();
常数s=fromEvent(
E
“更新”
).烟斗(
以(4)为例,
map(()=>Math.random()>0.3?1:2),
点击(v=>console.log('pre',v)),//pre-log
开关映射(异步(i)=>[
等待承诺。解决((i+1)==2),
我
]作为常量),
轻触(v=>console.log('post',v)),//post log
过滤器(([f,])=>f),
map(([,p])=>p)
);
s、 订阅(v=>console.log('result',v));
for(设i=0;i<4;i++){
e、 发出(“更新”,1);
//等待新的承诺(res=>setTimeout(res,1000));-如果我取消注释,它会工作
}

这里我看到
console.log('pre',v)
评估了4次,但
console.log('post',v)
只评估了一次。如果我取消对for循环中的sleep的注释,一切都会按预期进行。

当您这样做时,这是一个同步发射,您将以一个事件结束,因为当源可观测发射时,switchMap将取消订阅/取消内部可观测,这在您的情况下是一个异步承诺

这与下面的场景类似

const e=new Subject();
e.pipe(switchMap(e=>timer(0).pipe(mapTo(e)))).subscribe(console.log)

for (let i = 0; i < 4; i++) {
  e.next('updated');
}
const e=新主题();
e、 管道(switchMap(e=>timer(0).管道(mapTo(e))).subscribe(console.log)
for(设i=0;i<4;i++){
e、 下一步(“更新”);
}
你最终只能得到一个“更新”。这里的解决方案之一是用
mergeMap
替换
switchMap

这确实是
开关映射的预期行为,其中您获得的发射数量取决于源发射与内部可观测发射的频率