Rxjs 在激活ajax请求时切换缓冲区
我正在尝试实现一个缓冲区,这样我就可以在ajax请求运行时组合事件,这样它们就可以基本上批处理在一起,并在ajax请求未运行时发送。例如,如果我有这样的东西:Rxjs 在激活ajax请求时切换缓冲区,rxjs,Rxjs,我正在尝试实现一个缓冲区,这样我就可以在ajax请求运行时组合事件,这样它们就可以基本上批处理在一起,并在ajax请求未运行时发送。例如,如果我有这样的东西: const updateQueue$ = new Subject<ISettings>(); // nothing in flight right now so this should go straight to the server updateQueue$.next({ volume: 30 }); // previ
const updateQueue$ = new Subject<ISettings>();
// nothing in flight right now so this should go straight to the server
updateQueue$.next({ volume: 30 });
// previous update is still in flight so queue this up
updateQueue$.next({ volume: 40 });
updateQueue$.next({ volume: 50 });
updateQueue$.next({ volume: 60, muted: true });
// original update finally finishes, combine all the latest
// items and send them now which should look something like
// this: { volume: 60, muted: true }
const updateQueue$=new Subject();
//现在没有任何东西在飞行中,所以应该直接发送到服务器
updateQueue$.next({volume:30});
//上一次更新仍在进行中,请将其排队
updateQueue$.next({volume:40});
updateQueue$.next({volume:50});
updateQueue$.next({volume:60,mute:true});
//原始更新最终完成,合并所有最新版本
//项目并立即发送它们,看起来应该是
//此:{volume:60,muted:true}
我有一个stackblitz为这个,但它不完全工作,因为我想,我不知道为什么
const allowSend$=新行为主体(true);
const updateQueue$=新主题();
更新$
.asObservable()
.烟斗(
点击(项目=>log(“添加到updateQueue$”的项目),项目)),
//在我看来,我这里似乎出了点问题,但我没能指出它。这似乎从来没有运行过。
缓冲开关(
allowSend$.asObservable().pipe(过滤器(allowSend=>!allowSend)),
() =>
allowSend$.asObservable().pipe(
过滤器(allowSend=>allowSend),
轻触(()=>“关闭缓冲区”)
)
),
轻触(缓冲区内容=>
log(“bufferContents预过滤器”,bufferContents)
),
过滤器(buffer=>!!buffer.length),
映射(缓冲区内容=>{
返回Object.assign({},…bufferContents);
}),
轻触(bufferContents=>console.log(“组合缓冲区”,bufferContents)),
//发送网络请求
开关映射(值=>{
allowSend$.next(false);
返回sendToServer(值为任意值);
}),
点击(()=>allowSend$.next(true))
//推送至主题以允许下一个去模糊值通过
//点击(()=>allowNext$.next(true))
)
.订阅(响应=>{
日志(“发送到服务器完成”);
});
间隔(2000年)
.烟斗(
地图(()=>{
updateQueue$.next(generateRandomEvent());
})
)
.subscribe();
您可以利用降低排放,直到指定的可观测排放。控制排放行为有两种设置:
-允许第一次发射通过前导
-允许最后一次发射通过(发射“指定可观测”之前的最后一次发射)尾随
油门
降低排放,然后在http调用完成后,调用。下一步
在触发器上观察,以便油门将恢复允许排放
我们可以使用它将所有排放累积到一个单一的变化对象中
因此,在简化形式中,这应该适用于您:
resume$=新主题();//用于告知“油门”允许排放
队列$=新主题();
工作$=此.queue$.pipe(
//将所有更新累积到单个更新对象中
扫描((acc,cur)=>({…acc,…cur}),{}),
节流(()=>this.resume$,{leading:true,training:true}),
concatMap(state=>this.updateState(state).pipe(
完成(()=>this.resume$.next())
))
);
由于节气门
控制排放,我认为一次只有一种排放物能够通过,因此我认为无论您选择开关映射
,concatMap
,合并映射
还是排气映射
,行为都不会有任何区别
看看这个例子
在这里,我更新了您的:-),因此,如果不需要合并结果,这将起作用。这些“设置”中的一些可能不具备所有功能。我在这里更新了stackblitz的“GeneratorAndomeEvent”fn:。这就是为什么我认为我需要使用缓冲区,而不是节流阀或concatmap之类的东西。我可以在每次更新时发送所有设置并限制它,但如果可以的话,我会尽量避免。简单修复。我们只需在其中添加一个
扫描
,即可将所有排放物合并到一个物体中。它可能会发送冗余字段,但我认为这可能是最不复杂的解决方案。我更新了SB。我非常感谢您的帮助。不过出于好奇,有没有理由不使用缓冲区操作符之一?看起来它们就是为这种情况而设计的。老实说,我不熟悉缓冲区运算符,这对我来说似乎更简单(可能是因为我不熟悉缓冲区运算符!):-)
const allowSend$ = new BehaviorSubject<boolean>(true);
const updateQueue$ = new Subject<ISettings>();
updateQueue$
.asObservable()
.pipe(
tap(item => log("item added to updateQueue$", item)),
// It seems to me I have *something* wrong here, but I haven't been able to pin point it. This doesn't appear to ever run.
bufferToggle(
allowSend$.asObservable().pipe(filter(allowSend => !allowSend)),
() =>
allowSend$.asObservable().pipe(
filter(allowSend => allowSend),
tap(() => "closing buffer")
)
),
tap(bufferContents =>
console.log("bufferContents pre filter", bufferContents)
),
filter(buffer => !!buffer.length),
map(bufferContents => {
return Object.assign({}, ...bufferContents);
}),
tap(bufferContents => console.log("combined buffer", bufferContents)),
// Send network request
switchMap(value => {
allowSend$.next(false);
return sendToServer(value as any);
}),
tap(() => allowSend$.next(true))
// Push to subject to allow next debounced value through
// tap(() => allowNext$.next(true))
)
.subscribe(response => {
log("done sending to server");
});
interval(2000)
.pipe(
map(() => {
updateQueue$.next(generateRandomEvent());
})
)
.subscribe();