forEach循环中的Javascript API队列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了forEach循环中的Javascript API队列相关的知识,希望对你有一定的参考价值。

目标摘要

我需要在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组合。您可以使一个队列功能以指定的时间间隔将其列队。

创建一个生成器函数基本上使一个apiCall并暂停

    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);
        }
    }

[还有另一种方法是结合使用setTimeoutPromise。这涉及创建在setTimeOut中解析并有足够延迟的promise。

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);
}

以上是关于forEach循环中的Javascript API队列的主要内容,如果未能解决你的问题,请参考以下文章

Web共享api javascript函数中的foreach值传递重复

转到 JavaScript forEach 循环中的“下一个”迭代 [重复]

@foreach 循环中的多种形式。如何使用 javascript 异步提交一个。 C# 核心剃刀

将数据从 javascript forEach 循环中的 php 数组发送到 ajax 调用的 url

如何在 ForEach 循环之后保留对象变量更改。 Javascript

原生 JavaScript 手写数组 API