Angular 4 从 ngOnInit 中的服务轮询/流数据

Angular 4 Poll / Stream Data from service within ngOnInit

我想使用 AngularJS 4 从 API 流式传输数据。当我第一次调用 API 时没有数据,但最终会在 15 - 30 秒内返回更多结果。

这是我的组件:

export class ResultsComponent implements OnInit {
    results: Results;

    constructor(
        private searchService: SearchService,
        private route: ActivatedRoute
    ) {}

    ngOnInit(): void {

        this.route.params
            .switchMap((params: Params) => 
        this.searchService.getResultsObservable(params['searchKey']))
            .subscribe(data => { this.results = data; });
}

这是我的服务电话:

我使用的是上面的 Observable 调用,但我也包含了 Promise 调用。

getResults(searchKey: string): Promise<Results> {
    const url = `${this.apiUrl}/${searchKey}/0`;
    return this.http.get(url)
            .toPromise()
            .then(response => response.json() || {})
            .catch(this.handleError);
}

getResultsObservable(searchKey: string): Observable<Results> {
    const url = `${this.apiUrl}/${searchKey}/0`;
    return this.http
            .get(url)
            .map(response => response.json() || {});
}

我认为我需要使用 Observable 调用,但我不确定我需要如何处理组件内的调用。

如果我对你的问题理解正确,你必须在特定时间间隔(比如 15 秒)后不断从服务器获取数据,你可以试试这个:

private keepGettingDataFromServer() {
    this.intervalLoop = setInterval (() => {
            this.getResultsObservable.subscribe(res => {
                //handle the response here
            })
        }
    }, 1500)
}

getResultsObservable(searchKey: string): Observable<Results> {
    const url = `${this.apiUrl}/${searchKey}/0`;
    return this.http
        .get(url)
        .map(response => response.json() || {});
}

ngOnDestroy() {
    if (this.intervalLoop) {
        clearInterval(this.intervalLoop);
    }
}

我也可以想到另一种方法,如果您的服务器是 ASP .NET,您可以使用 SignalR 订阅频道并在收到预期数据时收到通知。

谢谢@mridula 让我走上正轨。经过一些研究,我发现最好的解决方案是使用 IntervalObservable:

subscription: Subscription;

ngOnInit() {
    this.route.params.subscribe(
      (params: Params) => {
        this.subscription = this.getResults((params['searchKey'])).subscribe(
          (response) => {
            console.log(response);
            //your business logic for each loop
            //once your are done
            this.stopInterval();
        }
      }
    );
  }
);

getResults(searchKey: string): {
      return IntervalObservable
      .create(1000) //1 second interval
      .flatMap(() => {
      return this.http.get('[API_URL]/' + searchKey).map(response => response.json());
  });
}

stopInterval(){
    this.subscription.unsubscribe();
}