【问题标题】:Angular 6 - run method in service every 10 secondsAngular 6 - 每10秒运行一次服务方法
【发布时间】:2018-11-08 04:36:44
【问题描述】:

我有这个服务使用 HttpClient 来获取一些数据:

checkData() {
    return this.http.get('my url');
}

页脚组件我调用它并显示结果:

ngOnInit() {
    this.myservice.checkdata().subscribe( result => { this.statustext = result } );
}

这可行,但我需要每 10 秒运行一次此方法,以便它是最新的。

我该怎么做?

【问题讨论】:

    标签: angular typescript rxjs angular6


    【解决方案1】:

    尝试使用来自 RxJS 的timer

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { Subscription, timer } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    
    import { MyService } from 'path/to/the/service/my-service.service';
    
    @Component({
      ......
    })
    export class MyExampleComponent implements OnInit, OnDestroy {
        subscription: Subscription;
        statusText: string;
        
        constructor(private myService: MyService) {}
    
        ngOnInit() {
            this.subscription = timer(0, 10000).pipe(
              switchMap(() => this.myService.checkdata())
            ).subscribe(result => this.statusText = result);
        }
    
        ngOnDestroy() {
            this.subscription.unsubscribe();
        }
    }
    

    来自 RxJS 的interval(10000) 是不合适的,因为它只会在 10 秒后才开始发出值,而不是第一次立即发出(我认为这不是你想要的)。

    但是,timer(0, 10000) 将立即 (0) 和每 10 秒 (10000) 发出值,直到取消订阅。

    【讨论】:

    • 小贴士,干净漂亮
    【解决方案2】:

    使用rxjs定时器在启动时调用api请求,然后每10秒调用一次。

    这最好通过使用 rxjs 分而治之来实现。

    首先,导入以下内容:

    import { timer, Observable, Subject } from 'rxjs';
    import { switchMap, takeUntil, catchError } from 'rxjs/operators';
    

    然后将处理请求的属性添加到api:

    private fetchData$: Observable<string> = this.myservice.checkdata();
    

    接下来,添加处理时间的属性:

    private refreshInterval$: Observable<string> = timer(0, 1000)
    .pipe(
      // This kills the request if the user closes the component 
      takeUntil(this.killTrigger),
      // switchMap cancels the last request, if no response have been received since last tick
      switchMap(() => this.fetchData$),
      // catchError handles http throws 
      catchError(error => of('Error'))
    );
    

    最后,如果组件被杀死,则触发 kill 命令:

    ngOnDestroy(){
      this.killTrigger.next();
    }
    

    这是StackBlitz Demo

    【讨论】:

      【解决方案3】:

      执行此操作的 rxjs 方法如下。

      import { interval } from 'rxjs/observable/interval';
      import { map } from 'rxjs/operators';
      
      const timeInterval$ = interval(10000);
      
      timeInterval$.pipe(
        map( () => this.http.get(//some url);
      );
      

      【讨论】:

        【解决方案4】:

        在您的 checkData 方法中,您可以执行以下操作:

        import { timer, of } from 'rxjs';
        import { switchMap, catchError } from 'rxjs/operators';
        
        checkData() {
            return timer(0, 10000)
                .pipe(
                   switchMap(_ => this.http.get('my url')),
                   catchError(error => of(`Bad request: ${error}`))
                );
        }
        

        那么你的订阅就会每10秒得到一次http调用的结果。

        【讨论】:

        • 这似乎有效,但一旦出现错误......即:没有互联网连接或找不到数据,它将停止循环
        • 如果在 http 请求中发生错误,则使用 catch 更新
        【解决方案5】:

        希望对你有帮助

        export class YourComponent implements OnInit, OnDestroy {
          private alive: boolean;
        
          constructor(){}
        
          ngOnInit(){
            this.alive = true;
            TimerObservable.create(0, 10000)
              .pipe(
                takeWhile(() => this.alive)
              )
              .subscribe(() => {
                this.myservice.checkdata().subscribe( result => { this.statustext = result } );
              });
          }
        
          ngOnDestroy(){
            this.alive = false;
          }
        }
        

        【讨论】:

          【解决方案6】:

          我指的是角度 8:

          请注意定时器和间隔的区别。

          如果您想延迟单个函数调用,您可以使用计时器,但如果您想按顺序触发多个函数调用,则需要使用倒置计时器,延迟时间介于:http://tutorials.jenkov.com/angularjs/timeout-interval.html

          我在这篇博文中发现了以下代码:http://tutorials.jenkov.com/angularjs/timeout-interval.html

          ngOnInit() {
              interval(5000)
                .pipe(
                  startWith(0),
                  switchMap(() => this.apiService.getTweets())
                )
                .subscribe(res => this.statuses = res.statuses})
              ;
            }
          

          【讨论】:

          • 您指的是 Angular 8,但提供了 AngularJS 的示例? :)
          【解决方案7】:

          你可以使用非常简单的setInterval

          setInterval(console.log('hi'), 10000);
          

          每 10 秒运行一次

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-04-16
            • 1970-01-01
            • 2022-01-11
            • 1970-01-01
            • 1970-01-01
            • 2019-06-14
            • 2015-01-18
            • 1970-01-01
            相关资源
            最近更新 更多