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

use*_*134 3 javascript rxjs ionic2 angular

我试图在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();
    })
    })

  }
Run Code Online (Sandbox Code Playgroud)

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

FRE*_*CIA 6

使用Observable.interval

\n\n
import {Observable} from \'rxjs/Rx\';\n...\nconstructor(...) {\n  Observable.interval(30000).subscribe(x => { // will execute every 30 seconds\n    this.ionViewDidLoad();\n  });\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者在你的ionViewDidLoad函数内:

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

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

\n\n
\n

timeInterval 运算符将源 Observable 转换为 Observable,该 Observable 发出源 Observable 连续发射之间经过的时间量的指示。这个新 Observable 的第一次发射表示观察者订阅该 Observable 的时间与源 Observable 发射其第一个项目的时间之间经过的时间量。没有相应的发射来标记源 Observable 的最后一次发射与随后对 onCompleted 的调用之间经过的时间量。

\n\n

timeInterval 默认情况下对超时Scheduler进行操作,但也有一个变体,允许您通过将其作为参数传递来指定 Scheduler。

\n
\n\n

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

\n

  • “时间间隔”有什么作用? (2认同)

Exp*_*lls 6

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

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

  getRandom() {
    return this.http.get('http://mywebserver.com/apps/random.php');
  }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以简单地调用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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 截至 2019 年 10 月 rxjs 6,`startWith()` 将不会立即触发调用。我们需要使用`startWith(0)` (2认同)