【问题标题】:Start first call of IntervalObservable instant开始第一次调用 IntervalObservable 瞬间
【发布时间】:2017-02-20 23:44:57
【问题描述】:

我正在使用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);
  }
}

那么我如何在第一次调用时立即调用服务器,然后在定义的延迟下调用服务器?

【问题讨论】:

    标签: angular typescript rxjs rxjs5


    【解决方案1】:

    两件事,

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

    【讨论】:

    【解决方案2】:

    您可以使用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);  
     }
    

    【讨论】:

      【解决方案3】:

      我会为此使用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 运算符。

      【讨论】:

      • 我尝试了这个解决方案,它也可以工作,但我选择了另一个,因为它更紧凑和清晰(在我的选择中)。但也谢谢!
      【解决方案4】:

      对于#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';
      

      【讨论】:

        猜你喜欢
        • 2018-06-29
        • 1970-01-01
        • 2020-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-07
        • 1970-01-01
        相关资源
        最近更新 更多