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

查看:72
本文介绍了如何使用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次调用,在init上使用):

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?

推荐答案

我有一个非常简洁的解决方案,其中您可以

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

  1. 发出请求的可观察对象.
  2. 另一个可观察到的东西,每隔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.

更新:感谢亚当,还有一个 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天全站免登陆