Javascript API Queue in forEach loop



目标摘要

我需要在我的 Node.js 后端实现一个 API 队列以进行 API 调用。 我需要遵守的 API 速率限制是每 2 秒 1 个请求,这是一个硬性限制。 我在 forEach 循环中进行 API 调用,因为我需要为每个用户执行一次 API 调用。

我在网上找到了很多关于如何创建队列的文章,但它们主要涉及向数组添加 API 调用,所以我不确定在这种情况下如何实现队列。

任何帮助都会得到极大的赞赏,如果有帮助,我可以分享更多代码。

法典

async function refreshStats() {
try {
// get list of all fortnite users
const fnUserList = await Users.find({}, "_id fnUserPlatform"); // my fnUser _id 5cca01ea8f52f40117b2ff51
fnUserList.forEach(async fnUser => {
//make  API call.  apiCall is a function I created to make the API call and format the response
const { lifeStats, statsEqual } = await apiCall(
fnUser.fnUserPlatform
);
//execute other functions with apiCall response
});
} catch (err) {
console.error("error in refreshStats", err);
}
}

如果我没看错的话。您可以利用generator functions并将其与setInterval相结合。您可以创建一个队列函数,以指定的时间间隔将其项目排队。

创建一个生成器函数基本上会发出api调用和暂停

async function* queueGenerator(userList) {
for (let fnUser of userList) {
const result = {lifeStats, statsEqual} = await apiCall(fnUser.fnUserPlatform);      
yield result;
}
}

然后在您的方法中创建一个队列并使用 setInterval 将项目排队

async function refreshStats() {
try {
// get list of all fortnite users
let handle;
const fnUserList = await Users.find({}, "_id fnUserPlatform"); // my fnUser _id 5cca01ea8f52f40117b2ff51
const queue = queueGenerator(fnUserList);
const results = [];
handle = setInterval(async () => {
const result = await queue.next();
results.push(result.value);
if (results.length === users.length) clearInterval(handle);
}, 2000);
} catch (err) {
console.error("error in refreshStats", err);
}
}

还有另一种方法是将setTimeoutPromises结合使用,这涉及创建承诺,这些承诺在setTimeOut中以足够的延迟解析。

async function refreshStatsV2() {
const fnUserList = await Users.find({}, "_id fnUserPlatform");
const promises = fnUserList.map((fnUser, ix) => (
new Promise(resolve =>
setTimeout(async() => {
const result = {
lifeStats,
statsEqual
} = await apiCall(ix.fnUserPlatform);
resolve(result);
}, ix * 2000) // delay every next item 2sec
)));
const result = await Promise.all(promises); // wait all
console.log(result);
}

最新更新