Add queueing to Angular's HttpClient

后端 未结 4 646
不思量自难忘°
不思量自难忘° 2020-12-29 00:39

I have exact same requirement as mentioned in Add queueing to angulars $http service but need implementation in Angular 4.3 or 5 using the HttpInterceptor from

4条回答
  •  生来不讨喜
    2020-12-29 00:55


    Solution


    @Zlatko has suggested correct approach, although there are few logical and syntax issues in it but I have corrected it pasting below a working code:

    import { Injectable } from '@angular/core';
    import { Response } from '@angular/http';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import { Subject } from 'rxjs/Subject'
    
    export class PendingRequest {
      url: string;
      method: string;
      options: any;
      subscription: Subject;
    
      constructor(url: string, method: string, options: any, subscription: Subject) {
        this.url = url;
        this.method = method;
        this.options = options;
        this.subscription = subscription;
      }
    }
    
    @Injectable()
    export class BackendService {
      private requests$ = new Subject();
      private queue: PendingRequest[] = [];
    
      constructor(private httpClient: HttpClient) {
        this.requests$.subscribe(request => this.execute(request));
      }
    
      /** Call this method to add your http request to queue */
      invoke(url, method, params, options) {
        return this.addRequestToQueue(url, method, params, options);
      }
    
      private execute(requestData) {
        //One can enhance below method to fire post/put as well. (somehow .finally is not working for me)
        const req = this.httpClient.get(requestData.url)
          .subscribe(res => {
            const sub = requestData.subscription;
            sub.next(res);
            this.queue.shift();
            this.startNextRequest();
          });
      }
    
      private addRequestToQueue(url, method, params, options) {
        const sub = new Subject();
        const request = new PendingRequest(url, method, options, sub);
    
        this.queue.push(request);
        if (this.queue.length === 1) {
          this.startNextRequest();
        }
        return sub;
      }
    
      private startNextRequest() {
        // get next request, if any.
        if (this.queue.length > 0) {
          this.execute(this.queue[0]);
        }
      }
    }
    

    One can use/call above service following way to make HTTP calls (from any other component or service) (Obviously you need to inject BackendService in the component e.g. Mention in provider of component and define in constructor):

        this.backendService.invoke('https://jsonplaceholder.typicode.com/posts', 'Get', null, null)
        .subscribe(
          result => {
            this.data = result;
          }
        );
    

    In case of someone wants to look at working plunker then here is the working plunker.

提交回复
热议问题