使用 observables 进行 Http 服务轮询

Http Service polling with observables

我正在尝试使用 Observables 在 Angular 2 中进行轮询。我知道还有许多其他答案,但我无法让它们为我工作。

我知道这是一个纯粹的理解问题,所以对答案的解释(它的作用和原因)而不是纯代码将不胜感激。

test.service.ts

@Injectable()
export class EtlService {

constructor(private http: Http) { }

//Get ETL by status
get(): Observable<EtlByStatus> {
    var url = 'someURL';

    return this.http
        .get(url)

        .map(response => {
            return {
                headers: response.json().data.headers,
                dataSet: response.json().data.data
            }
        });
}

通过简单的订阅调用此服务将按预期工作:

this._service
            .get()
            .subscribe(
                res=> {
                    this.headers= res.headers;
                    this.data = res.dataSet;
});

但是,我的问题是轮询。据我所知,轮询应该从 Component 内部完成,以允许服务更可重用 - HTTP 请求很简单,可以通过多种方式处理。

test.component.ts

pollGet(timer: number = 30000): Observable<GetInterface> {
        return Observable.interval(timer)
            .switchMap((res) => {
                this._service.get();
            })
            .map(res => res)
            .subscribe(res => {
                console.log('testing');
            })
    }

上面的return是res => void is not assignabletype void is not assignable to type ObservableInput。我试过将中间的 get 行变成 return,这会产生更多错误和 returns 消息,表明 subscribe 是一个函数。

因此,您如何使用 Observables 进行投票?我确信这是我对 mapswitchMapsubscribe 的理解,以及它们如何作为 observable 的一部分发挥作用,但我无法理解。

你的函数 pollGet 根据可重用原则参与 return Observable<GetInterface>,所以 finally 订阅不适合这里因为它会将 return 类型变为 subscription.

关于switchMap

switchMap用于组合observable链,Observable中的switchMap是基于原始Observable的结果。所以在这里你应该 return 在 switchMap.

中输入 Observable

根据您的代码,switchMap 中的可观察值与任何原始可观察结果无关,因此在这里您可以简单地使用 map.

所以最终的工作代码块如下:

pollGet(timer: number = 30000): Observable<any> {
    return Observable
               .interval(timer)
               .map(() => {
                   //return this.http.get('111');
                   // make sure your r_service.get return an Observable as the example above: http.get
                   return this._service.get();
               })
               .map(res => res);
}

您的地图需要在 switchMap 中。我确实相信 switchMap 在这里是正确的用法,因为您想 return 一个新的可观察对象,而不是 interval 发出的整数。您需要做的是附上您的地图以处理 http/service 响应。

pollGet(timer: number = 30000): Observable<GetInterface> {
  return Observable.interval(timer)
    .switchMap((intervalCounter) => {
      return this._service.get() // note that you need a return here, or inline return
        .map(res => res);
    })
    .subscribe(res => {
      console.log('testing');
    })
}