Angular2 RxJS定期回复http请求(轮询)

时间:2017-03-20 12:40:50

标签: angular typescript rxjs

我使用Angular2 2.4.8。我使用Http服务获取数据:

fetchData(urls: string[], computer: Computer): Observable<Computer> {
    let stream$ = <Subject<Computer>>new Subject();
    let requests = new Map<string, Observable<Response>>();
    urls.forEach(url => {
        requests.set(url, this.http.get(url));
    });
    Observable.forkJoin(Array.from(requests, x => x[1]))
        .subscribe((responses: Response[]) => {
            // put data from responses into computer (API gives data in pieces)
            stream$.next(computer);
            stream$.complete();
        },
        (e: Response) => {
            // do something with error
            stream$.error(e.json());
        });
    return stream$.asObservable();
}

现在我需要定期刷新数据(轮询)。困难在于不同网址的频率应该不同。我可以使用Rx来实现这个目标吗?

也许代替参数urls: string[]我可以通过url和fefresh频率传递对象数组。但我不知道如何在Rx中解决这个问题。

2 个答案:

答案 0 :(得分:1)

如果您想定期发出HTTP请求,则需要使用.interval。这将允许您偶尔“触发”新请求。

例如:

function poll (tuple) {
  return Rx.Observable.combineLatest(
    tuple.map(({url, time}) => {
      return Rx.Observable
        .interval(time)
        .switchMap(val => Rx.Observable.of(`${url}: ${val}`));
    })
  );
}

poll([
  { url: 'foo', time: 500 },
  { url: 'bar', time: 100 }
]).subscribe(val => console.log(val));
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

Rx.Observable.of部分替换为http服务。

答案 1 :(得分:0)

这实际上取决于您正在尝试做什么以及如何处理从fetchData()返回的Observable。

一般情况下,如果您想定期重复请求,可以使用repeatWhen()运算符并将其与delay()链接:

urls.forEach(url => {
    requests.set(url, this.http.get(url)
      .repeatWhen(notifier => notifier.delay(XXX)));
});

此外,如果您想重复请求,则无法使用forkJoin(),因为它只会发出值并立即完成。

在这种情况下,combineLatest()zip()似乎都很好,具体取决于您希望实现的目标。