我正在使用fetch对第三方API进行API调用。我有多个访问令牌来帮助阻止我达到他们的速率限制。我遇到的问题是循环工作不正常。在初始循环之后,只调用数组中的第二个键,因此达到API限制。
这是代码:
// outside of function scope for keeping track of which key to use
let count = -1;
export default async function apiCall(
request_type: string,
url: string,
request_body?: RequestInit,
headers?: HeadersInit
) {
const keys: string[] = [
`${env.API_KEY_0}`,
`${env.API_KEY_1}`,
`${env.API_KEY_2}`,
`${env.API_KEY_3}`,
];
if (count === 4) {
await wait(5);
count = 0;
}
const request: RequestInit = {
method: request_type,
headers: headers
? headers
: {
"Content-Type": "application/json",
"Access-Token": `${keys[count]}`,
},
};
if (request_type !== "GET" && request_type !== "DELETE") {
request.body = JSON.stringify(request_body);
}
// used to switch the tokens to prevent rate_limiting. Faster than using a rate limiter in each function
count++;
console.log(keys[count]);
// return await fetch(`https://api.com/${url}`, request)
// .then((result) => {
// return result.json();
// })
// .catch((error) => {
// console.log(error);
// });
}
const wait = (seconds = 1) => {
new Promise((r) => setTimeout(r, seconds * 1e3));
};
这是控制台输出,显示它在第四次函数调用后没有等待:
API_KEY_1
API_KEY_2
API_KEY_3
undefined
API_KEY_1
API_KEY_1
API_KEY_1
API_KEY_1
API_KEY_1
...
编辑
部分问题是等待函数没有返回,但即使在等待函数调用完成后,它也没有正确重置,如console.log中所示:
API_KEY_1
API_KEY_2
API_KEY_3
undefined
Waiting...
API_KEY_1
API_KEY_1
API_KEY_1
API_KEY_1
API_KEY_1
...
这里有一个游乐场,可以更好地了解我所看到的:https://playcode.io/968433
期望的结果是:
API_KEY_1
API_KEY_2
API_KEY_3
API_KEY_4
Waiting...
API_KEY_1
API_KEY_2
API_KEY_3
API_KEY_4
Waiting...
...
这是因为您没有从wait
函数中return
和Promise
。试试这个:
const wait = (seconds = 1) => new Promise((r) => setTimeout(r, seconds * 1e3));
如果您想可靠地循环通过这些API键并在结束时短暂等待,请从count = -1
开始,就像您第一次创建它时一样:
// (No change so far)
let count = -1;
也可能没有理由每次都重新创建数组,所以在count
旁边的函数之外(也没有理由使用`${env.API_KEY_0}`
等,除非你必须从某个东西转换为字符串,如果你需要转换,似乎不太可能只使用env.API_KEY_0
或String(env.API_KEY_0)
(:
const keys: string[] = [
env.API_KEY_0,
env.API_KEY_1,
env.API_KEY_2,
env.API_KEY_3,
];
然后,在你的功能开始时:
if (++count === 4) {
await wait(5);
count = 0;
}
并移除改变CCD_ 9的任何其它代码。
然后在请求中使用"Access-Token": keys[count]
(同样不需要模板文字(。