Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fire a new http request only when the first one is completed and ignore/cancel all the other requests in between

Tags:

I am making the front-end of an SPA with Angular2 and I have a database with lots of records and the database itself is very slow, so taking 10000 records (or just the last 10 of them with ORDER BY) takes up to 4-5 seconds. In my situation upgrading a database is not an option.

So what I want to do is: when a user clicks on paginator's "next" button (onNextClick is already called) multiple times (let's say he is continuously clicking up to 100 times or more), only the first http request would be sent to the Server/API. Now is the part where I can't manage to figure it out:

WHEN the first request comes back with a result, THEN the last clicked event fires a new request ignoring all other click requests in between the first and the last one (ignored should be requests, but not the clicks themselves). THEN, if the user is still clicking, the last click/request becomes the first one and so on...

I tried to do that with RxJS, but I only managed to do that by using interval, so if interval is 600 ms and the user is clicking every 1000ms, all the requests are sent to server. Here's my code:

 private clickStream = new Subject();

 ngOnInit() {
   this.clickStream
   .debounce(() => Observable.interval(600).take(1))
   .subscribe(
     params => {
       this.callHttpPostMethod();
     }
   );
 }

 onNextClick(event) {
     this.clickStream.next(event);
 }

Any Angular2 solution would be welcome - using RxJS is not a requirement.

like image 411
Marius B Avatar asked Mar 14 '17 08:03

Marius B


1 Answers

You can cancel in-flight requests and ensure that only the latest request is being handled by using switchMap:

this.clickStream
    .debounceTime(500)
    .switchMap(e=> this.callHttpPostMethod())
    .subscribe(t=> {
          ... do something ...
     });
like image 187
pixelbits Avatar answered Oct 04 '22 23:10

pixelbits