[英]How is it possible to stop a debounced Rxjs Observable?
我創建了一個 observable,它將在最后一次更改后 3 秒觸發,並調用服務的publishChange
。 它有效,但我想創建一個doImmediateChange
function,它立即調用publishChange
並停止去抖動的 observable。 這怎么可能?
我的組件:
class MyComponent {
private updateSubject = new Subject<string>();
ngOnInit() {
this.updateSubject.pipe(
debounceTime(3000),
distinctUntilChanged()
).subscribe(val => {
this.srv.publishChange(val);
});
}
doChange(val: string) {
this.updateSubject.next(val);
}
doImmediateChange(val: string) {
// Stop the current updateSubject if debounce is in progress and call publish immediately
// ??
this.srv.publishChange(val);
}
}
您可以使用switchMap
和delay
模擬debounceTime
。 然后使用takeUntil
取消內部 Observable 以防止發出等待值。
private updateSubject = new Subject<string>();
private interrupt = new Subject();
ngOnInit() {
this.updateSubject.pipe(
switchMap(val => of(val).pipe(
delay(3000),
takeUntil(this.interrupt)
))
).subscribe(val => publish(val));
}
doChange(val: string) {
this.updateSubject.next(val);
}
doImmediateChange(val: string) {
this.interrupt.next();
publish(val);
}
使用競賽運算符:
第一個完成的 observable 成為唯一訂閱的 observable,所以這個遞歸的 function 將在一次發射后完成take(1)
,然后() => this.raceRecursive()
。
private timed$ = new Subject<string>();
private event$ = new Subject<string>();
ngOnInit() {
this.raceRecursive()
}
raceRecursive() {
race(
this.timed$.pipe(debounceTime(1000)),
this.event$
)
.pipe(take(1)) // force it to complete
.subscribe(
val => console.log(val), // srv call here
err => console.error(err),
() => this.raceRecursive() // reset it once complete
)
}
doChange(val: string) {
this.timed$.next(val)
}
doImmediateChange(val: string) {
this.event$.next(val)
}
您可以使用debounce和race實現此行為:
使用您提供的代碼
private destroy$ = new Subject<void>();
private immediate$ = new Subject<void>();
private updateSubject$ = new Subject<string>();
constructor(private srv: PubSubService) {}
ngOnInit() {
this.updateSubject$.pipe(
takeUntil(this.destroy$),
debounce(() => race(timer(3000), this.immediate$))
).subscribe(val => {
this.srv.publishChange(val);
});
}
doChange(val: string, immediate?: boolean) {
this.updateSubject$.next(val);
if (immediate) this.immediate$.next();
}
// don't forget to unsubscribe
ngOnDestroy() {
this.destroy$.next();
}
立即發出更改將立即替換先前的正常更改(即去抖 3 秒),而不會延遲(感謝我們的種族可觀察)。
這是一個工作示例
您可以為每個值提供一個特定於值的去抖時間,並使用帶timer
的去debounce
來動態更改值的去抖時間。
private updateSubject = new Subject<{ value: any, debounceTime: number}>();
ngOnInit() {
updateSubject.pipe(
debounce(({ debounceTime }) => timer(debounceTime)),
pluck('value')
).subscribe(val => publish(val));
}
doChange(value: string) {
updateSubject.next({ value, debounceTime: 3000 });
}
doImmediateChange(value: string) {
updateSubject.next({ value, debounceTime: 0 });
}
這不會直接停止去抖動的 Observable,但讓我們“覆蓋”一個等待值,並以零延遲發射一個新值。
https://stackblitz.com/edit/rxjs-j15zyq
(user733421 似乎不想添加完整的解決方案,所以我擴展了方法)
debounceTime 的值僅在可觀察的創建時間評估一次。
為了能夠動態更新 debounceTime,請將 debounce 與計時器一起使用,如下所示:
debounce(()=>timer(this.debounceTime)),
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.