RxJS中的竞争条件?

RxJS中的竞争条件?,rxjs,Rxjs,我目前正在开发RxJS组件,该组件的作用是定期从数据库中提取一些数据,使其作为行为主体可观察并可供客户端使用 /“制作人” const source2=Observable.create((观察者:观察者)=>{ this.fooService.loadFoos()。然后((val)=>{ 下一个观察员(val) 观察员:完成() }) }) const subc=new BehaviorSubject(new Map()) 间隔(5000)。管道( 开关映射(()=>source2), ).订

我目前正在开发RxJS组件,该组件的作用是定期从数据库中提取一些数据,使其作为行为主体可观察并可供客户端使用

/“制作人”
const source2=Observable.create((观察者:观察者)=>{
this.fooService.loadFoos()。然后((val)=>{
下一个观察员(val)
观察员:完成()
})
})
const subc=new BehaviorSubject(new Map())
间隔(5000)。管道(
开关映射(()=>source2),
).订阅(subc)
//“客户”
回流管(
first(),//仅获取最新数据,这是一个带有foos数字键的映射
地图((f:map)=>{
如果(!f.has(fooId)){
抛出新错误('foo not found')
}
返回f
}),
).toPromise()
它工作得很好,除非在罕见的情况下,当间隔开始时,与switchMap f/value一起的某个地方看起来像一个空白映射。这是在使用apache基准测试的压力测试下复制的

为什么会这样?上面的代码有什么问题吗?是因为switchMap的取消效应吗

这就是它失败的频率:

并发级别:100
测试时间:6.620秒
完成申请:5000
失败的请求:1230

这不是一个明确的答案,但它太长了,无法发表评论:-)


您的BehaviorSubject以默认值
new Map()
开始,因此在您的间隔第一次触发(5000ms)和第一次promise调用返回之前发生的任何订阅都将收到一个空映射

如果需要replay功能,但不是默认值,则可以使用
ReplaySubject

const subc=新的ReplaySubject(1);
是因为switchMap的取消效应吗

不。switchMap不会只返回一个空数组,当它“切换”时,它只会删除以前可观察源的发射,并且只传播新源的发射

getFoos()
是否可能返回空映射

笔记: 您的“producer”函数基本上是
from()
(|),因此您可以使用:

const source2=from(this.fooService.loadFoos());
如果您没有调用subject.next任何地方,您可以完全摆脱subject,只需执行以下操作:

const subc=间隔(5000)。管道(
startWith(新映射()),
开关映射到(源2),
共享重播(1)
);

感谢您的有益解释和提示。“getFoos()是否可能返回空映射?”是-经过一点调试后,不幸的是,这就是问题的原因:\