如何限制并行 api 请求

Abb*_*ain 7 javascript concurrency multithreading

问题是我有一个 API 任务列表,但问题是我无法同时从我的端点到服务器访问超过 3 个 API(这是服务器限制,它不会响应同一请求的 URL,该 URL 具有更多处理中调用的 API 数量少于 3 个)。因此,我找到了一种方法来完成此任务,但我知道有一种更好的方法,但对如何做没有任何线索,但我找到了一个简单的解决方案,即依次点击 API 并等待响应,然后点击另一个,但这需要太多时间

更优化的解决方案如果N = 3,那么我将同时执行taskList中的'task1','task2'和'task3'。一旦任务 2 完成,您就可以执行“任务 4”,依此类推。这是我想要在不使用任何库的情况下实现的解决方案。

const taskList = [
  "task1",
  "task2",
  "task3",
  "task4",
  "task5",
  "task6",
  "task7",
  "task8",
  "task9",
  "task10",
];

const dummyAPICalled = (task) => {
  console.log(task, "started");
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log(task, "ended");
      resolve(true);
    }, Math.random() * 20000);
  });
};
Run Code Online (Sandbox Code Playgroud)

依次点击调用的API并等待响应。

for await (const task of taskList) {
    await dummyAPICalled(task);
}
Run Code Online (Sandbox Code Playgroud)

同时并行访问所有 API,但由于服务器要求而未得到响应

const promises = taskList.map((task) => dummyAPICalled(task));
Run Code Online (Sandbox Code Playgroud)

Ste*_*eve 5

并发承诺

由于您需要并发 API 请求,因此您需要在先前的实例解析之前创建多个实例。当每个单独的请求得到解决后,您可以为每个实例发出另一个 API 请求。您可以将多个 Promise 组合在一起,并Promise.all在所有实例解析时解析。

它可能看起来像这样:

function callTasks(concurrentLimit) {
  var currentTask = 0;
  async function createTaskInstance() {
    while (currentTask < taskList.length) {
      // currentTask is a variable that's shared across
      // all of the task instances
      await dummyAPICalled(taskList[currentTask++]);
    }
  }
  var tasks = [];
  for (let i = 0; i < concurrentLimit; i++) {
    tasks.push(createTaskInstance());
  }
  return Promise.all(tasks);
  // or alternatively:
  // return Promise.all([...Array(concurrentLimit)].map(createTaskInstance));
}
Run Code Online (Sandbox Code Playgroud)

例如,使用问题中的代码:

function callTasks(concurrentLimit) {
  var currentTask = 0;
  async function createTaskInstance() {
    while (currentTask < taskList.length) {
      // currentTask is a variable that's shared across
      // all of the task instances
      await dummyAPICalled(taskList[currentTask++]);
    }
  }
  var tasks = [];
  for (let i = 0; i < concurrentLimit; i++) {
    tasks.push(createTaskInstance());
  }
  return Promise.all(tasks);
  // or alternatively:
  // return Promise.all([...Array(concurrentLimit)].map(createTaskInstance));
}
Run Code Online (Sandbox Code Playgroud)