在Angular / RxJs中,如何捆绑http请求,以便一个捆绑包包含多个请求(http:// test / 1,http:// test / 2等)

时间:2018-08-08 23:28:39

标签: angular rxjs

我一直在看bufferTime rxjs运算符,并且本质上是想用它来捆绑http请求(this.http.get<string>('http://test/?id={num}'))。{num}是1-4。我想要的是捆绑这些请求每2秒。因此,如果2秒内发出2个请求,则它们看起来像:

this.http.get<string>('http://testUrl?id=1')this.http.get<string>('http://testUrl?id=2'),它们将作为1个请求发送到服务器(我指的是捆绑)。服务器将收到'http://testUrl?id=1,2'

感谢您的阅读!

2 个答案:

答案 0 :(得分:0)

forkJoin允许您并行触发您的请求,因此可以“捆绑”您的请求。

首先创建您的延迟的Observables数组:

let obs = Array
    .from({length: 100}, (v, k) => k + 1)
    .map(x =>
        this.http.get<string>('http://test/{x}')
            .pipe(concatMap(item => of(item.pipe(delay(2000)))))
    );

然后只需使用forkJoin即可将它们解雇:

forkJoin(obs)
    .subscribe(x=>{
        console.log(x)//an array of response from HTTP
    })

以上代码仅在2*(100-1) = 198秒内完成

答案 1 :(得分:0)

所以我修改了一下代码。现在,两个请求主体通过数组合并为一个主体。每3秒就会发送一组请求正文以及url:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Subject, Subscriber, Observable } from 'rxjs';
import { debounceTime } from 'rxjs/operators/debounceTime';
import { buffer } from 'rxjs/operators/buffer';

interface ReportRunStatus {
    status: any;
}

interface RequestWithObserver {
    request: number;
    observer: Subscriber<ReportRunStatus>;
}

const DEBOUNCE_TIME = 3000;

@Injectable()
export class WelcomeService {
    private requests = new Subject<RequestWithObserver>();
    private bufferTrigger = new Subject<null>();
    private requestBuffer = this.requests.pipe(buffer(this.bufferTrigger.pipe(debounceTime(DEBOUNCE_TIME))));

    constructor(
        private http: HttpClient
    ) {
        this.subscribeBufferRequests();
    }

    public getConfig(id: number) {
        return new Observable((observer) => {
            this.bufferTrigger.next(null);

            this.requests.next({
                request: id,
                observer
            });
        });
    }

    public subscribeBufferRequests() {
        this.requestBuffer.subscribe((requests) => {
            const requestsData = requests.map((r) => r.request);
            this.http.post('getMovie', requestsData).subscribe((response) => {
                requests.forEach((requestItem, i) => {
                    requestItem.observer.next(response[i]);
                });
            });
        });
    }
}