所以我从 api 中获取
一组带有速率限制的 url,目前我通过为每个调用添加超时来处理这个问题,如下所示:
const calls = urls.map((url, i) =>
new Promise(resolve => setTimeout(resolve, 250 * i))
.then(() => fetch(url)
)
);
const data = await Promise.all(calls);
在每次调用之间强制等待 250 毫秒。这可确保永远不会超过速率限制。
事实是,这并不是真正必要的。我已经尝试过 0 毫秒的等待时间,大多数情况下我必须在 api 开始返回之前重复重新加载页面四到五次:
{ 错误:{ 状态:429,消息:“超出 API 速率限制”}}
大多数情况下,您只需等待一秒钟左右即可安全地重新加载页面并获取所有数据。
更合理的方法是收集返回 429 的调用(如果返回 429),等待一段设定的时间然后重试它们(也许重做设定的次数)。
问题,我对如何实现这一点感到有点困惑?
编辑:
刚回到家,会仔细查看答案,但似乎做出了一个我认为没有必要的假设:调用不必顺序,它们可以被解雇(并返回) ) 以任何顺序。
最佳答案
您想要的术语是指数退避。您可以修改您的代码,使其在某个失败条件下继续尝试:
const max_wait = 2000;
async function wait(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
const calls = urls.map(async (url) => {
let retry = 0, result;
do {
if (retry !== 0) { await wait(Math.pow(2, retry); }
result = await fetch(url);
retry++;
} while(result.status !== 429 || (Math.pow(2, retry) > max_wait))
return result;
}
或者您可以尝试使用库来为您处理退避,例如 https://github.com/MathieuTurcotte/node-backoff
关于javascript - Node ,等待并重试失败的 api 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57274602/