首先启动IntervalObservable即时调用

时间:2016-10-12 08:37:30

标签: angular typescript rxjs rxjs5

我使用IntervalObservable来连续调用我的应用程序的服务器端。我可以订阅和取消订阅Oberservable,一切正常,只有一个例外:

对服务器的第一次调用被延迟了,但我希望它是即时的。 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);
  }
}

那么如何在第一次通话时及之后使用定义的延迟呼叫服务器?

4 个答案:

答案 0 :(得分:8)

两件事,

  1. 您可以使用工厂方法代替派生类型,即Observable.interval(3000)代替IntervalObservable.create
  2. 您可以使用timer代替单个运算符:

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

答案 1 :(得分:5)

您可以使用startWith

以下示例在创建流时在流上推送事件:

 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);  
 }

答案 2 :(得分:2)

我会使用concatconcatMap

查看现场演示: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));

第一个请求由Observable.of(null)触发,该httpRequest通过运营商链并触发Observable.interval。然后全部由"packagename"+".permission.C2D_MESSAGE" 运算符决定。

答案 3 :(得分:1)

对于#RxJS版本5+:

您可以使用rxjs interval operator并实施投票。以下实现将每1000毫秒间隔执行this.statusService.getStatus()行:

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

现在添加startWith(1),它将立即执行,没有任何延迟,之后每隔1秒执行一次。 我想这就是你想要的。

或另一种方法:您可以使用timer operator并执行以下操作:

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

在这种方法中,计时器操作员将立即执行,之后每1000毫秒执行一次。

也不要忘记导入:

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