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

问题描述 投票:3回答:2

我试图在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秒获取新数据

javascript angular ionic2 rxjs
2个回答
3
投票

使用Observable.interval

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

或者你的ionViewDidLoad函数内:

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的时间与源Observable发出第一个项目的时间之间经过的时间。没有相应的排放标记在源Observable的最后一次发射和随后的onCompleted调用之间经过的时间量。

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

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


5
投票

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

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

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

现在你可以简单地在randomService.getRandom()中调用setInterval,但你也可以使用observable操作(例如有一个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)",你不必手动取消订阅。

© www.soinside.com 2019 - 2024. All rights reserved.