简体   繁体   English

首先启动IntervalObservable即时调用

[英]Start first call of IntervalObservable instant

I'm using an IntervalObservable to make continuous calls to the server side of my application. 我正在使用IntervalObservable来连续调用我的应用程序的服务器端。 I can subscribe and unsubscribe to to the Oberservable and everything works fine with one exception: 我可以订阅和取消订阅Oberservable,一切正常,只有一个例外:

The first call to the server is delayed, but I want it to be instant. 对服务器的第一次调用被延迟了,但我希望它是即时的。 The behaviour of the IntervalObservable is in principle correct, but does not match my requirements. IntervalObservable的行为原则上是正确的,但不符合我的要求。

@Injectable()
export class LoggerService {
  constructor(private http: Http) { }
  private apiURL = 'assets/file.json'; 

  getList() {
       return IntervalObservable.create(1000).flatMap(() 
       => this.http.get(this.apiURL))
      .map(this.extractData)
      .catch(this.handleError);
  }
  private extractData(res: Response) {
    var fooot = new Foo();
    fooot.fillFromJSON(JSON.stringify(res.json()));
    return fooot;
  }

  private handleError(error: any) {
    let errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg);
    return IntervalObservable.throw(errMsg);
  }
}

So how can I call the server instant on the first call and afterwards with the defined delay? 那么如何在第一次通话时调用服务器,然后以定义的延迟调用服务器?

Two things, 两件事情,

  1. You can use the factory methods instead of the derived types, ie Observable.interval(3000) instead of IntervalObservable.create 您可以使用工厂方法而不是派生类型,即Observable.interval(3000)而不是IntervalObservable.create
  2. You can use timer to do it with a single operator instead: 您可以使用timer来代替单个操作员:

     return Observable.timer(0, 1000) .flatMapTo(this.http.get(this.apiURL)) .map(this.extractData) .catch(this.handleError); 

You can use startWith . 你可以使用startWith

Following example pushes an event on the stream when it is created: 以下示例在创建流时在流上推送事件:

 getList() {
    return IntervalObservable.create(1000)
     .startWith(1) // needs a value, but won't be used
     .flatMap(() => this.http.get(this.apiURL))
     .map(this.extractData)
     .catch(this.handleError);  
 }

I'd use concat and concatMap for this: 我会使用concatconcatMap

See live demo: http://plnkr.co/edit/4kdJRD7HZqrbce7MFPW7 观看现场演示: http//plnkr.co/edit/4kdJRD7HZqrbce7MFPW7

import {Observable} from 'rxjs';

let httpRequest = () => Observable.of('response');

Observable.of(null)
  .concat(Observable.interval(3000))
  .concatMap(httpRequest)
  .subscribe((response) => console.log(response));

The first request is triggered with Observable.of(null) which goes through the operator chain and triggers httpRequest . 第一个请求是用Observable.of(null)触发的,它通过运算符链并触发httpRequest Then it's all up to the Observable.interval operator. 然后全部由Observable.interval运算符决定。

For #RxJS Version 5+ : 对于#RxJS版本5+:

You can use rxjs interval operator and implement polling. 您可以使用rxjs interval运算符并实现轮询。 The following implemention will execute the this.statusService.getStatus() line in every 1000 ms interval : 以下实现将每1000毫秒间隔执行this.statusService.getStatus()行:

 getList() {
     return Observable.interval(1000).startWith(1)
     .mergeMapTo(this.http.get(this.apiURL))
     .catch(this.handleError);
}

With startWith(1) added, now, it will be immediately executed without any delay and after that it will be executed every 1 sec interval. 现在,添加startWith(1) ,它将立即执行,没有任何延迟,之后每隔1秒执行一次。 I think this is what you want. 我想这就是你想要的。

Or Another approach: you can use timer operator and do the following: 或另一种方法:您可以使用计时器操作符并执行以下操作:

getList() {
    return Observable.timer(0, 1000)
      .mergeMapTo(this.http.get(this.apiURL))
      .catch(this.handleError);
}

In this approach, the timer operator will instantly execute and after that it will execute in every 1000 ms. 在这种方法中,计时器操作员将立即执行,之后将每1000毫秒执行一次。

Also don't forget to import : 另外别忘了导入:

  import {Observable} from 'rxjs/Observable';
  import 'rxjs/add/operator/startWith';
  import 'rxjs/add/operator/mergeMapTo';
  import 'rxjs/add/observable/timer';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM