typescript 如何在特定时间间隔后获取数据,同时使用Angular 中的rxjs可观值获取来自API的动态数据

x4shl7ld  于 2023-01-03  发布在  TypeScript
关注(0)|答案(3)|浏览(122)

我尝试从一个API获取数据并使用RxJs Observables在我的Angular 应用程序中动态更新它,我的代码的问题是我使用的api对每小时可以发出的请求数量有限制。我如何修改我的服务和组件,使数据在特定时间(例如5分钟)后动态获取和更新?

服务代码:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Observable, Subject } from 'rxjs';
import { tap } from "rxjs/operators";

@Injectable({
  providedIn: 'root'
})
export class ApiserviceService {

  constructor(private http: HttpClient) { }
  private _refreshreq = new Subject<void>();

  get refresh(){
    return this._refreshreq;
  }
  getfng(): Observable<object>{
    return this.http.get('https://api.testapi.com/fng/').pipe(
      tap(()=>{
        this.refresh.next();
      })
    )
  }
  getcdata() : Observable<object>{
    return this.http.get('https://api.testapi.com/v2/data/').pipe(
      tap(()=>{
        this.refresh.next();
      })
    )
  }
}

组件代码:

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { ApiserviceService } from '../services/apiservice.service';

@Component({
  selector: 'app-homecomponent',
  templateUrl: './homecomponent.component.html',
  styleUrls: ['./homecomponent.component.css']
})
export class HomecomponentComponent implements OnInit {
  fngdata: any;
  value: any;
  class: any;
  datarray: any;
  ngOnInit(): void {
    this.getfngindex();
    this.getdata();
    this.service.refresh.subscribe(response=>{
      this.getfngindex();
      this.getdata();
    })
  }
  constructor(private service: ApiserviceService) { }
  getfngindex(){
    return this.service.getfng().subscribe((data:any)=>{
      this.fngdata = data.data[0]
      console.log(this.fngdata);

      this.value =this.fngdata.value
      this.class =this.fngdata.value_classification
    })
  }
  getdata(){
    return this.service.getcdata().subscribe((data:any)=>{
      this.datarray = data.data;
      console.log(this.datarray[0]);
    })
  }

}
kxkpmulp

kxkpmulp1#

当调用一个可观察对象时,你可以简单地使用repeat操作符和给定的延迟选项。
例如,在getdata方法中,您可以简单地执行以下操作:

const FIVE_MINUTES_MS =  5 * 60 * 1_000;

this.service.getcdata()
  .pipe(
    repeat({ delay: FIVE_MINUTES_MS })
  )
  .subscribe((data:any) => {
    this.datarray = data.data;
      console.log(this.datarray[0]);
  })

这将无限期地触发,但是如果要限制调用次数,还可以设置count属性
您可以找到有关repeathere的更多信息

vzgqcmou

vzgqcmou2#

我在组件ts文件的ngOnInit()代码中进行了以下更改,以获得所需的功能:

组件代码:

import { interval } from 'rxjs';
ngOnInit(): void {
    this.getfngindex();
    this.getdata();
    const datatimelimit = interval(60000) //fetches and updates the data after every 1 minute
    const fngtimelimit = interval(4*60*60*1000) //fetches and updates the data after every 4 hours
    datatimelimit.subscribe(response=>{
      this.getdata();
    })
    fngtimelimit.subscribe(response=>{
      this.getfngindex();
    })
  }
zbq4xfa0

zbq4xfa03#

您可以在每次通话结束后启动间隔的“开始”,以下内容可能会对您有所帮助:

import { finalize, debounce } from 'rxjs';

ngOnInit(): void {
    this.getfngindex(0);
    this.getdata(0);
}

constructor(private service: ApiserviceService) { }

getfngindex(waitingTime: number) {
    return this.service.getfng().pipe(
        debounceTime(waitingTime),
        finalize(() => this.getfngindex(4 * 60 * 60 * 1000))
    ).subscribe((data: any) => {
        this.fngdata = data.data[0]
        console.log(this.fngdata);

        this.value = this.fngdata.value
        this.class = this.fngdata.value_classification
    })
}

getdata(waitingTime: number) {
    return this.service.getfng().pipe(
        debounceTime(waitingTime),
        finalize(() => this.getfngindex(60000))
    ).subscribe((data: any) => {
        this.datarray = data.data;
        console.log(this.datarray[0]);
    })
}

据我所知,interval的问题在于我们在滥发API(如果它是带有免费增值计划的API,我们必须谨慎):下一个呼叫可以在前一个呼叫还没有完成的情况下被触发。
多亏了debounce操作符,观察值将在XX毫秒后触发(初始化时为0)。使用finalize操作符,冷却重新启动,以触发下一个请求(即使它是错误的)。
像这样我们可以确定每个请求的冷却在API响应后重新开始。在这个例子中要小心,因为this.refresh.next()debounce完成之前被调用。但是这个想法是这样的:)

相关问题