离子限制API调用

时间:2019-01-25 11:19:25

标签: angular api ionic-framework limit

我正在使用3rd party库在Ionic中使用Spotify的API(我不是直接从我的代码中进行HTTP查询),并且试图限制每秒发送的请求数。

我的期望:

  • 我可以为每个请求设置一个延迟时间
  • 或设置每秒的最大允许请求数,并且当我需要发送超过每秒最大允许的请求数(这是我设置的数字)时,这部分代码(库,我的代码等)将排队请求并稍后发送。

我不是Ionic的专家,也不是Angular的专家。 我尝试过:

const apiCalls = [];

//in a for loop
apiCalls.push(fromPromise(this.spotifyApi.getArtistRelatedArtists(sourceArtist.mbid)).delay(this.apiDelay).toPromise());

//then
concat(...apiCalls).subscribe(

似乎没有任何效果,例如,我发送了20个请求,并且apiDelay为1秒,它们都在不到2秒的时间内完成了。

我尝试使用像这样的库: simple-rate-limiter 但是它们只能与'require'一起使用,而Ionic则抱怨:

  

找不到模块的声明文件

如何在Ionic中延迟对外部API的请求?

2 个答案:

答案 0 :(得分:1)

也许您可以尝试以下简单方法,演示https://stackblitz.com/edit/angular-http-client-kfnniw

// mock some random requests
for (let i = 0; i < 10; i++) {
  setTimeout(() => this.httpCalls.push({
    id: i,
    request: this.http.get<any[]>(this.apiUrl)
  }), Math.random() * 5000);
}

// handle queue
let interval = setInterval(() => {
  let toRun = this.httpCalls.splice(0, 5);
  for (let i = 0; i < toRun.length; i++) {
    ((r) => {
      let s = new Subject();
      r.request.subscribe(s);
      this.httpResponses.push({ id: r.id, subject: s });
    })(toRun[i]);
  }
}, 1000);

// in some other places, process actual requests
setInterval(() => {
  let r = this.httpResponses.splice(0, this.httpResponses.length);
  for (let i = 0; i < r.length; i++) {
    r[i].subject.subscribe(data => {
      console.log(`finished request ${r[i].id}`);
    });
  }
}, 1000);

答案 1 :(得分:0)

我通过将代码更改为类似的方式解决了该问题。 它基本上使用setTimeout来延迟API调用的开始。

const apiCalls = [];
let i = 0;

//in a for loop
apiCalls.push(this.getRelatedArtistsWithDelay(i * this.apiDelay, sourceArtist.id[this.PROVIDER]));
i++;

//then
concat(...apiCalls).subscribe(

//and the getRelatedArtistsWithDelay function calls the API with a delayed start
  private getRelatedArtistsWithDelay(delay, artistId){
    return new Promise(resolve => {
      setTimeout(() => {
        this.spotifyApi.getArtistRelatedArtists(artistId).then((data) => {
          resolve(data);
        })
      },
      delay)
    });
  }