【问题标题】:How do I poll a service using RXJS Observables?如何使用 RXJS Observables 轮询服务?
【发布时间】:2017-05-30 05:10:34
【问题描述】:

给定以下代码,如何更改它以使“api/foobar”的获取请求每 500 毫秒重复一次?

import {Observable} from "RxJS/Rx";
import {Injectable} from "@angular/core";
import {Http} from "@angular/http";

@Injectable() export class ExampleService {
    constructor(private http: Http) { }

    getFooBars(onNext: (fooBars: FooBar[]) => void) {
        this.get("api/foobar")
            .map(response => <FooBar[]>reponse.json())
            .subscribe(onNext,
                   error => 
                   console.log("An error occurred when requesting api/foobar.", error));
    }
}

【问题讨论】:

  • 我在stackoverflow.com/a/42659054/2398593 回答了一个类似的问题,问题是我没有使用interval,因为如果您的通话时间超过 500 毫秒,另一个将被解雇。我的回答解决了这个问题:)

标签: angular typescript rxjs observable polling


【解决方案1】:

确保您已从rxjs/Rx 导入{Observable}。如果我们不导入它,有时会出现可观察到的未找到错误。

工作 plnkr http://plnkr.co/edit/vMvnQW?p=preview

import {Component} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'app',
    template: `
      <b>Angular 2 HTTP polling every 5 sec RxJs Observables!</b>
      <ul>
        <li *ngFor="let doctor of doctors">{{doctor.name}}</li>
      </ul>

      `
})

export class MyApp {
  private doctors = [];
  pollingData: any;      

  constructor(http: Http) {
   this.pollingData = Observable.interval(5000)
    .switchMap(() => http.get('http://jsonplaceholder.typicode.com/users/')).map((data) => data.json())
        .subscribe((data) => {
          this.doctors=data; 
           console.log(data);// see console you get output every 5 sec
        });
  }

 ngOnDestroy() {
    this.pollingData.unsubscribe();
}
}

【讨论】:

  • 这可能很危险 - 如果请求花费的时间超过 5000,则下次运行 switchMap 时,它将取消先前的请求。因此,如果您的所有请求都花费了超过 5000 个,那么每个请求都会取消下一个请求,并且您不会获得任何轮询。 (5000 应该是安全的,但 500 太小了)
  • 如果您担心请求花费的时间太长,请使用 concatMap,因为它会跟踪每个请求并以正确的顺序处理它们。
  • 如果您不想为第一个数据等待 5 秒:.interval(5000).startWith(0)
  • 它运行良好,但是当 api 出现错误时,整个间隔中断。
  • @ideep 尝试在 subscribe err 参数中捕获您的错误。我忘记在订阅中添加错误参数
【解决方案2】:

试试这个

return Observable.interval(2000) 
        .switchMap(() => this.http.get(url).map(res:Response => res.json()));

【讨论】:

  • 感谢您的回复。在我看来,这似乎也行得通。但是,我收到此错误:EXCEPTION: Observable_1.Observable.interval is not a function。我正在使用 RxJS 版本 5-beta。回滚到版本 4 是否可以解决这个问题?
  • 我猜你可以在 package.json 文件中
【解决方案3】:

为什么不试试setInterval()?

setInterval(getFooBars(), 500);

【讨论】:

  • 为什么这个答案被否决了?像我这样的读者会对为什么这个答案“不好”感兴趣。
  • 它被否决了,因为这是一个不使用可观察模式的常规间隔,而问题是如何使用可观察的轮询(间隔)机制。此外,使用 setInterval 方法应强制函数 getFooBars 每 500 毫秒执行一次并触发 API,无论是否返回响应都无法取消。使用 observables,当再次触发相同的 api 时,可以取消 api 的执行。
  • 如果你使用 angularjs 是一个很好的解决方案,但是对于 angular+ 最好使用 Observable 方法
猜你喜欢
  • 1970-01-01
  • 2021-12-29
  • 2020-04-16
  • 1970-01-01
  • 2020-05-05
  • 2016-05-02
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多