4

我有一个数据服务,它会在其他服务需要时定期触发 http 调用。现在,此服务异步工作,因此可能会在前一个尚未完成时请求数据服务触发 http 调用。

我想知道当我需要进行 http 呼叫时如何使用 rxjs 检查是否有正在进行的呼叫

数据服务:

constructor(private http: HttpClient){}

// if this gets called while another hasn't returned, wait for it and then trigger the next http call
public request(method, url, options): Observable<any>{
    return this.http.request(method, url, options);
}

服务一:

public syncA(){
    setTimeout(() => {
       this.dataService.request('GET', 'someUrl', someOptions).subscribe((response) => {
        console.log('periodic call returns ', response});
    }, 45000);
}

服务乙:

public doB(): Observable<any>{
 return this.dataService.request('GET', 'someUrl', someOptions)
}

这种情况是当服务 B 调用 doB 而 syncA 已触发请求但尚未完成时。

4

2 回答 2

3

执行此操作的 rxjs 方法是使用concatMapTo

正如stackblitz 示例所示

const fakeRequest = of('Network request complete').pipe(delay(3000));
//wait for first to complete before next is subscribed
const example = sampleInterval.pipe(concatMapTo(fakeRequest));
//result
//output: Network request complete...3s...Network request complete'
const subscribe = example.subscribe(val => console.log(val));
于 2019-09-06T16:03:09.833 回答
0

您可以使用 behaviorSubject 来存储加载道具并仅在它为假时才释放管道,如下所示:

private loading = new BehaviouSubject<boolean>(false);

constructor(private http: HttpClient){}

// if this gets called while another hasn't returned, wait for it and then trigger the next http call
public request(method, url, options): Observable<any>{
    return this.loading.pipe(
        filter(value => value === false),
        take(1),
        tap(() => this.loading.next(true)),
        mergeMap(() => this.http.request(method, url, options)),
        tap(() => this.loading.next(false))
    );
}
于 2019-09-05T19:02:26.530 回答