typescript - RxJS fördröj minst X millisekunder
Jag försöker implementera följande beteende i RxJS:
- Utlös ett evenemang
- Anropa ett HTTP-API
När API:et returnerar, antingen:
- Vänta tills minst X millisekunder har förflutit sedan händelsen utlösts
- Returnera omedelbart om X millisekunder redan har passerat sedan händelsen utlösts
Detta skulle vara mycket användbart för UX, eftersom även om anropet tar 1 ms vill jag visa en laddningsikon i minst 100 ms.
Jag har inte heller hittat något sätt att implementera detta med delay, throttle, debounce eller dess variationer.
this.eventThatFires
.switchMap(data => {
let startTime = Date.now();
return this.callHttpService(data)
.delay(new Date(startTime + 1000));
})
Jag antog att något sådant fungerade, men att använda ett absolut datum verkar göra en tidsdifferens med den aktuella tiden, och inte schemalägga försening för den absoluta tiden.
REDIGERA :
Det verkar inte finnas någon inbyggd operator som fungerar som det jag beskriver. Jag skapade den precis eftersom jag kommer att använda den mycket i hela min applikation:
import { Observable } from "rxjs/Observable";
function delayAtLeast<T>(this: Observable<T>, delay: number): Observable<T> {
return Observable.combineLatest(
Observable.timer(delay),
this)
.map(([_, i]) => i);
}
Observable.prototype.delayAtLeast = delayAtLeast;
declare module "rxjs/Observable" {
interface Observable<T> {
delayAtLeast: typeof delayAtLeast;
}
}
Svar #1
Effektivt är fördröjning efter datum samma som fördröjning efter nummer, den enda skillnaden är att fördröjningsperioden beräknas som skillnaden mellan det angivna datumet och aktuell tid.
Du kan använda delayWhen-operatorn för att beräkna fördröjning när ett värde emitteras:
this.eventThatFires
.switchMap(data => {
let startTime = Date.now();
return this.callHttpService(data)
.delayWhen(() => Rx.Observable.timer(500 + startTime - Date.now()))
})
Svar #2
Vad är fel på din combineLatest-lösning?
Du kan också använda zip:
this.eventThatFires
.switchMap(data => Observable.zip(
this.profileService.updateInfo(profileInfo)),
Observable.timer(500),
x => x));
