【发布时间】:2021-01-12 03:13:14
【问题描述】:
我正在使用 TypeScript 编写 API 包装器。我希望代码是异步的,以便最大限度地满足相关 API 的速率限制。 API 希望以 1/秒的最大速率提交请求。
我打算实现一个实例化一次的 API 包装器,并允许使用对象到达不同的端点。例如,在更大的 API 中有一个 post 和 pool 端点。我想像post_object.post.submit_request(argument1, ...) 或post_object.pool.submit_request(argument1, ...) 一样访问它们。
我创建了一个名为 state_info 的对象,该对象在各种对象之间传递,其中包含用户代理标头、登录信息(如果提供)以及来自瓶颈库的速率限制器对象。
我在测试时遇到的问题是我的程序似乎实际上并没有限制请求的速率;无论我将瓶颈参数中的限制更改为什么,每次请求都会在大约 0.600 秒内发生。
我认为这与传递速率限制器对象或从多个位置访问它有关,但我不确定。
首先,这里是 Model 对象的代码,它表示对 API 的访问。
import axios, { AxiosRequestConfig } from "axios";
import { StateInfo, Method } from "./interfaces";
export class Model {
public stateInfo: StateInfo;
constructor(stateInfo: StateInfo) {
// Preserve rate limiter, user agent, etc.
this.stateInfo = stateInfo;
}
//Updated to funcName = () => {} syntax to bind "this" to this class context.
private submit_request = (query_url: string, method: Method) => {
if (this.stateInfo.username && this.stateInfo.api_key) {
const axiosConfig: AxiosRequestConfig = {
method: method,
url: query_url,
headers: { "User-Agent": this.stateInfo.userAgent },
auth: {
username: this.stateInfo.username,
password: this.stateInfo.api_key,
},
};
return axios(axiosConfig);
} else {
const axiosConfig: AxiosRequestConfig = {
method: "get",
url: query_url,
headers: { "User-Agent": this.stateInfo.userAgent },
};
return axios(axiosConfig);
}
};
public submit_throttled_request = (url: string, method: Method) => {
return this.stateInfo.rateLimiter.schedule(
this.submit_request,
url,
method
);
};
}
然后,我调用这个类的代码:
import { Model } from "./models/model";
import Bottleneck from "bottleneck";
const limiter: Bottleneck = new Bottleneck({ mintime: 1000, maxconcurrent: 1 });
const stateInfo = {
rateLimiter: limiter,
userAgent: "email@website.com | API Dev",
};
let modelObj: Model = new Model(stateInfo);
async function makeRequest() {
try {
let response = await modelObj.submit_throttled_request(
"https://www.website.com/api",
"get"
);
console.log(response.data.id + "|" + Date.now());
} catch (err) {
console.log(err);
}
}
let start = new Date();
for (let i = 0; i < 20; i++) {
makeRequest();
}
我的预期是,如果每秒只能提交一个请求,该操作至少需要 10 秒。然而,无论我为 mintime 添加什么内容,我的平均水平都是一半。
【问题讨论】:
标签: javascript typescript api asynchronous rate-limiting