angular - switchMap och debounceTime avbryter väntande
Jag har en metod som kommer att söka efter anställda baserat på ett sökord.
this._sub.pipe(
debounceTime(500),
filter(x => !!x),
distinctUntilChanged(),
switchMap(this.getResults.bind(this))
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
this._sub.next('mySearchTerm');
Detta fungerar utmärkt, tidigare API-anrop avbryts om ett nytt utfärdas. Men här uppstår problemet.
Aktiva API-anrop avbryts endast när debounce har skickat ut. Om ett aktivt API-anrop returnerar medan debouncen väntar, utlöser det fortfarande min prenumeration.
Jag förstår att detta beror på att avbokningen endast sker inom omfattningen av switchmap.
Är det möjligt att refaktorera detta så att om debouncen väntar på att inmatningen ska sluta, kommer det att avbryta eventuella väntande API-anrop?
Förmodligen ett naivt tillvägagångssätt, men jag försökte något liknande nedan, det avger värden men nu finns det ingen debounce-effekt.
this._sub.pipe(
filter(x => !!x),
distinctUntilChanged(),
switchMap((x) => {
return of(x)
.pipe(
debounceTime(500),
this.getResults.bind(this)
);
})
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
Tack för all hjälp.
Svar #1
Använd takeUntil för att avbryta dina förfrågningar när this._sub sänder.
this._sub.pipe(
debounceTime(500),
filter(x => !!x),
distinctUntilChanged(),
switchMap(searchTerm => this.getResults(searchTerm).pipe(
takeUntil(this._sub)
))
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
Svar #2
Det accepterade svaret bör fungera bra, men jag ville dela ett annat sätt du kan göra detta med timer istället för debounceTime:
this._sub.pipe(
filter(x => !!x),
distinctUntilChanged(),
switchMap(val => timer(500).pipe(
switchMap(() => this.getResults(val))
))
).subscribe(...);
Nu, om en emission når switchMap, kommer timer och allt i den (inklusive en aktiv nätverksförfrågan) att avbrytas, och en ny timer kommer att skapas.
