http每隔x秒以角度请求一次

时间:2017-12-19 14:28:12

标签: javascript angular ionic2 rxjs

我试图在angular2中每隔x秒刷新一次http调用。

  ionViewDidLoad() {

    let loader = this.LoadingController.create({
      'content':'Please Wait'
    });
    loader.present().then(()=>{
      this.http.request('http://mywebserver.com/apps/random.php').map(res=> res.json()).subscribe(data=>{
        console.log(JSON.stringify(data));
        loader.dismiss();
        this.fact = data;
      },err=>{
        loader.dismiss();
        let alert = this.alertCtrl.create({
          title: 'Error!',
          subTitle: 'Please check your Internet Connectivity',
          buttons: ['OK']
        });
      alert.present();
    })
    })

  }

我在新加载页面时获取数据。但现在我的问题是刷新http调用以每隔x秒获取新数据

2 个答案:

答案 0 :(得分:5)

我会创建一个单独的服务来发出你的http请求:

@Injectable()
export class RandomService {
  constructor(http: HttpClient) { }

  getRandom() {
    return this.http.get('http://mywebserver.com/apps/random.php');
  }
}

现在您只需在randomService.getRandom()内调用setInterval,但您也可以使用可观察操作(例如Observable.interval)来ionViewDidLoad为您处理此问题}:

async function ionViewDidLoad() {
  let loader = this.LoadingController.create({
    content: 'Please Wait',
  });
  await loader.present();

  // x number of seconds
  this.interval$ = interval(x).pipe(
    // make first request right away; otherwise we have to wait x seconds before first one
    startWith(),

    // cancel previous request if it had not finished yet
    switchMap(() =>
      // catch the error inside to allow for a retry each time
      // you could also use `.catch` on the entire observable stream which will
      // cancel it if there's an error.
      this.randomService.getRandom().catch(err => {
        console.error(err);
        this.alertCtrl
          .create({
            title: 'Error!',
            subTitle: 'Please check your Internet Connectivity',
            buttons: ['OK'],
          })
          .present();
      }),
    ),
  );

  this.interval$.subscribe(data => this.fact = data);

  // Separate observable to dismiss loader on first emission
  this.interval$.pipe(first()).subscribe(() => loader.dismiss());
}

ionViewWillUnload() {
  this.interval$.unsubscribe();
}

注意:这是假设使用RxJS 5.5和Angular与HttpClient。你可能没有这些,但你仍然可以做一些非常相似的事情。你只是无法通过lettable运算符进行管道传输,如果你没有使用HttpClient,你仍然必须执行.map(data => data.json())我将在服务中执行此操作。

最后,如果可以,请避免存储和手动取消订阅,如this.interval$中所述。相反,您可能会执行类似this.fact$ = interval(x)...的操作。然后在您的模板中,您可以执行*ngFor="let fact of (fact$ | async)",而无需手动取消订阅。

答案 1 :(得分:3)

使用Observable.interval

import {Observable} from 'rxjs/Rx';
...
constructor(...) {
  Observable.interval(30000).subscribe(x => { // will execute every 30 seconds
    this.ionViewDidLoad();
  });
}

ionViewDidLoad函数内的OR:

Observable.interval(3000)
          .timeInterval()
          .flatMap(() => this.http.request('http://mywebserver.com/apps/random.php')
          .map(res=> res.json())
          .subscribe(data=>{
              console.log(JSON.stringify(data));
              loader.dismiss();
              this.fact = data;
            });

编辑以回答您的评论。来自Rxjs文档:

  

timeInterval运算符将源Observable转换为   可观察到发出的时间间隔的指示   连续排放的源Observable。第一次发射   从这个新的Observable中可以看出它之间经过的时间   观察者订阅Observable的时间和时间   当源Observable发出第一个项目时。没有   相应的发射标志着之间经过的时间   最后一次发射源Observable和随后的调用   onCompleted。

     

默认情况下,timeInterval在超时Scheduler上运行,但也是   有一个变体,允许您通过传递它来指定调度程序   作为参数。

在这种情况下,它基本上是JavaScript的原生setInterval()函数的反应/ Rxjs方式。