如何使用Angular 2中的rxjs按间隔请求异步

时间:2017-01-26 07:56:35

标签: angular rxjs rxjs5

我想使用rxjs在http请求中设置间隔。我需要在请求完成后n秒内在服务器上发送数据。

Observable.interval(10000)
                  .?(() => {
                      //request for server. return Observable
                      return this.getData();
                  })
                  .subscribe(() => {
                      console.log("Request done. After 10 second will be next request");
                  });

更新基于Mark

建议的.expand()
ngOnInit() {
  this.getData()
    .expand(() => Rx.Observable.timer(10 * 1000)
      .concatMap(() => this.getData())
    )
    .subscribe(data => {
      console.log('received new data', data);
    });
}

private getData() {
  return Observable.timer(5000)
    .do(() => console.log("timer"));
}

3 个答案:

答案 0 :(得分:3)

我认为你想每隔几秒就要求服务器。你能这样试试

吗?

确保你已经从'rxjs / Rx'导入了导入{Observable}如果你没有导入它我们有时会发现observable not found错误

工作plnkr http://plnkr.co/edit/vMvnQW?p=preview

import {Component} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'app',
    template: `
      <b>Angular 2 HTTP request every 5 sec RxJs Observables!</b>
      <ul>
        <li *ngFor="let doctor of doctors">{{doctor.name}}</li>
      </ul>

      `
})

export class MyApp {
  private doctors = [];

  constructor(http: Http) {
    Observable.interval(5000)
    .switchMap(() => http.get('http://jsonplaceholder.typicode.com/users/')).map((data) => data.json())
        .subscribe((data) => {
          this.doctors=data; 
           console.log(data);// see console you get output every 5 sec
        });
  }
}

请参阅Google检查控制台,您将每5秒获取一次新数据

答案 1 :(得分:3)

您的用例是.expand运算符的一个很好的例子,它可以递归地执行和返回新值。请参阅此片段,其中我添加了大量时间戳+调试日志以澄清发生了什么。

&#13;
&#13;
function getData() {
  // simulate remote call which can take some time
  return Rx.Observable.of('')
    .timestamp()
    .do(i => console.log(`[debug] Going to fetch data from server @${i.timestamp}`))
    .map(i => 'the new JSON blob of data to use') // this would be your actual http.get call
    .delay(1500)
    .timestamp()
    .do(i => console.log(`[debug] Data retreived from server @${i.timestamp}`));
}

getData()
  .expand(_ => Rx.Observable.of('') // we need something to delay upon
    .timestamp()
    .do(i => console.log(`[debug] Waiting 1sec for next getData ${i.timestamp}`))
    .delay(1000)
    .concatMap(() => getData())
  )
  .take(5)
  .subscribe(val => console.log(`New data received @${val.timestamp} : ${val.value}`))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>
&#13;
&#13;
&#13;

所以最初您订阅getData()并在检索下一个delay之前将其值扩展为递归getData()一段时间。此方法不涉及任何主题,您的订阅仍可用于接收新值。

答案 2 :(得分:1)

我已经阅读了您在删除的答案中添加的评论。您想发送请求,然后在收到响应后10秒发送另一个请求。

这很复杂,但可行......我认为这样的事情应该有效:

let responseSubject = new Rx.BehaviourSubject({});
responseSubject
    .delay(10000)
    .flatMap(() => {
        return http.get(...)
    })
    .subscribe((res) => {
        responseSubject.onNext({});
        // Your stuff here
    });

我在此设置行为,以便在收到回复时提供反馈。然后设置一个流,在请求10秒后,它发出请求并产生响应。

编辑:我错过了某些内容......第一个请求在启动前需要10秒钟。然后我会改写为:

let responseSubject = new Rx.ReplaySubject(1);
responseSubject
    .delay(10000)
    .startWith({})
    .flatMap(() => {
        return http.get(...)
    })
    .subscribe((res) => {
        responseSubject.onNext({});
        // Your stuff here
    });