如何使用 angular2 限制每秒 API 调用 [英] How to limit API calls per second with angular2

查看:24
本文介绍了如何使用 angular2 限制每秒 API 调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 API 限制为每秒 10 次调用(但每天数千次),但是,当我运行此函数时(调用对象的每个样式 ID,> 每秒 10 次):

I have an API limit of 10 calls per second (however thousands per day), however, when I run this function (Called each Style ID of object, > 10 per second):

  getStyleByID(styleID: number): void {
    this._EdmundsAPIService.getStyleByID(styleID).subscribe(
      style => {this.style.push(style); },
      error =>  this.errorMessage = <any>error);
  }

来自这个函数(只有 1 次调用,使用 onInit):

from this function (only 1 call, used onInit):

  getStylesWithoutYear(): void {
    this._EdmundsAPIService.getStylesWithoutYear(this.makeNiceName, this.modelNiceName, this.modelCategory)
      .subscribe(
        styles => { this.styles = styles;
                      this.styles.years.forEach(year =>
                        year.styles.forEach(style =>
                          this.getStyleByID(style.id)));

        console.log(this.styles); },
        error =>  this.errorMessage = <any>error);
  }

它每秒进行 > 10 个调用.如何限制或减慢这些调用以防止出现 403 错误?

It makes > 10 calls a second. How can I throttle or slow down these calls in order to prevent from getting a 403 error?

推荐答案

我有一个非常巧妙的解决方案,您可以将两个 observables.zip() 运算符:

I have a pretty neat solution where you combine two observables with the .zip() operator:

  1. 发出请求的可观察对象.
  2. 另一个 observable 每 0.1 秒发出一个值.

您最终会每 0.1 秒发出一个可观察的请求(= 每秒 10 个请求).

You end up with one observable emitting requests every .1 second (= 10 requests per second).

这是代码(JSBin):

// Stream of style ids you need to request (this will be throttled).
const styleIdsObs = new Rx.Subject<number>();

// Getting a style means pushing a new styleId to the stream of style ids.
const getStyleByID = (id) => styleIdsObs.next(id);

// This second observable will act as the "throttler".
// It emits one value every .1 second, so 10 values per second.
const intervalObs = Rx.Observable.interval(100);

Rx.Observable
  // Combine the 2 observables. The obs now emits a styleId every .1s. 
  .zip(styleIdsObs, intervalObs, (styleId, i) => styleId)
  // Get the style, i.e. run the request.
  .mergeMap(styleId => this._EdmundsAPIService.getStyleByID(styleId))
  // Use the style.
  .subscribe(style => {
    console.log(style);
    this.style.push(style);
  });

// Launch of bunch of requests at once, they'll be throttled automatically.
for (let i=0; i<20; i++) {
  getStyleByID(i);
}

希望您能够将我的代码转换为您自己的用例.如果您有任何问题,请告诉我.

Hopefully you'll be able to translate my code to your own use case. Let me know if you have any questions.

更新:感谢 Adam,还有一个 JSBin 展示了如何在请求不一致的情况下限制请求(请参阅评论中的 convo).它使用 concatMap() 运算符而不是 zip() 运算符.

UPDATE: Thanks to Adam, there's also a JSBin showing how to throttle the requests if they don't come in consistently (see convo in the comments). It uses the concatMap() operator instead of the zip() operator.

这篇关于如何使用 angular2 限制每秒 API 调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆