获取RxJS Observable立即返回初始数据,然后每隔X秒重复一次?

时间:2017-12-11 22:10:41

标签: angular rxjs observable

以下是每隔 30秒给出结果的代码示例,但是,当组件订阅该服务时,还必须等待30秒数据集:

getTasks(query: string): Observable<any> {
  return this._http.get(this._ripcord + '/tasks' + query, this.getHttpOptions())
    .map((response: Response) => <any>response.json())
    .delay(30000)
    .repeat()
    .do(data => console.log(data))
    .catch(this.handleError);
}

我看了similar issue on stack,但这个解决方案对我不起作用。

有没有人知道我可以组合使用哪个运算符来在订阅时立即检索初始数据?

4 个答案:

答案 0 :(得分:1)

谢谢大家,因为他们帮助我创建了自己的解决方案!

getTasks(query: string): Observable<any> {
  return Observable
    .timer(0, 30000)
    .switchMap(() =>
      this._http.get(this._ripcord + '/tasks' + query, this.getHttpOptions())
        .map((response: Response) => <any>response.json())
        .do(data => console.log(data))
        .catch(this.handleError)
    );
}

OR

getTasks(query: string): Observable<any> {
  return Observable
    .interval(30000)
    .startWith(0)
    .switchMap(() =>
      this._http.get(this._ripcord + '/tasks' + query, this.getHttpOptions())
        .map((response: Response) => <any>response.json())
        .do(data => console.log(data))
        .catch(this.handleError)
    );
}

OR

getTasks(query: string): Observable<any> {
  return Observable
    .timer(0, 30000)
    .switchMap(() =>
      this._http.get(this._ripcord + '/tasks' + query, this.getHttpOptions())
        .map((response: Response) => <any>response.json())

    )
    .do(data => console.log(data))
    .catch(this.handleError);
}

我意识到我需要利用 switchMap ,因为map在订阅getETsks端点的Http服务GET响应时返回了一个Observable。您可以选择将DO和CATCH运算符放在switchMap而不是map运算符上。

答案 1 :(得分:0)

interval.startWith(在您指向的解决方案中引用)确实是答案。

我怀疑你真正想要的是:

Observable
  .interval(30000)
  .startWith(0)
  .map(event =>
    this._http.get(this._ripcord + '/tasks' + query, this.getHttpOptions())
  )
  .do(data => console.log(data))
  .catch(this.handleError);

答案 2 :(得分:0)

您可以使用timer。使用计时器,您可以指定何时应该开始排放。下面的示例立即发出第一个值,然后需要5秒才能发出后续值。

var sourceTimer = Rx.Observable
        .timer(0, 5000)
        .timeInterval()
        .take(10);

var subscriptionTimer = sourceTimer.subscribe(
        function (x) {
            console.log('Next: ' + JSON.stringify(x));
        },
        function (err) {
            console.log('Error: ' + err);
        },
        function () {
            console.log('Completed');
        });

<强>输出:

Next: {"value":0,"interval":4}
Next: {"value":1,"interval":5004}
Next: {"value":2,"interval":5000}

Interval&amp; startWith也可以正常工作,立即发出零值,您将其作为参数提供给startWith,然后在提供的时间间隔内发出后续值。

  var source = Rx.Observable
    .interval( 5000 /* ms */)
    .startWith(0)
    .timeInterval()
    .take(10);

 var subscription = source.subscribe(
    function (x) {
        console.log('Next: ' + JSON.stringify(x));
    },
    function (err) {
        console.log('Error: ' + err);
    },
    function () {
        console.log('Completed');
    });

<强>输出:

Next: {"value":0,"interval":1}
Next: {"value":0,"interval":5003}
Next: {"value":1,"interval":5000}

Next: {"value":7,"interval":5000}
Next: {"value":8,"interval":5001}

答案 3 :(得分:0)

如果您需要在http请求返回错误时保持可观察序列,请在发出请求时捕获错误并返回空的observable。

  getTasks(query: string): Observable<any> {
    return Observable
      .interval(30000)
      .startWith(0)
      .switchMap(event => {
        this._http
          .get(this._ripcord + '/tasks' + query, this.getHttpOptions())
          .catch(error => Observable.empty());
      })
      .map((response: Response) => <any>response.json())
      .do(data => console.log(data))
      .catch(this.handleError);
  }

否则序列将在第一个错误时停止。