JS多个HTTP请求限制最大并发数

在JavaScript中,可以使用Promiseasync/await结合的方式来实现限制最大并发数的并行请求。以下是几个示例代码:

1、实例一:
const arr = Array.from({ length: 100 }, (value, index) => index + 1); // 生成一个包含100个元素的数组

// 模拟一个异步请求,每个请求用Promise包装
const fetchData = (num) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Request', num, 'finished');
      resolve();
    }, Math.random() * 1000); // 使用随机的延迟模拟请求时间
  });
};

const sendRequest = async (urls, concurrentLimit) => {
  const tasks = urls.map((url) => fetchData(url));
  const results = [];

  for (let i = 0; i < tasks.length; i += concurrentLimit) {
    const currentTasks = tasks.slice(i, i + concurrentLimit);
    await Promise.all(currentTasks).then((result) => {
      results.push(...result);
      console.log('Batch finished:', i + concurrentLimit);
    });
  }

  console.log('All requests completed');
  return results;
};

sendRequest(arr, 10);

在上面的示例代码中,我们首先使用Array.from方法生成了一个包含100个元素的数组。然后,我们使用fetchData函数模拟了一个异步请求,并将每个请求用Promise包装起来。

接下来,我们定义了一个sendRequest函数来发送请求。该函数接受两个参数:urls是要发送请求的数组,concurrentLimit是限制的最大并发数。

在函数内部,我们使用map方法将每个请求任务封装成Promise对象并保存在tasks数组中。然后,我们使用for循环来分批处理请求任务。每次循环从tasks数组中取出concurrentLimit个任务,并使用Promise.all方法来等待这些任务完成。一旦每一批任务都完成,我们会将结果保存到results数组中,并输出一条批次完成的消息。

最后,我们在sendRequest函数的最后输出一条所有请求完成的消息,并返回results数组。

通过这种方式,我们可以限制最大并发数为10,快速发送100个HTTP请求,并等待所有请求都完成后返回结果。

2、改进机制

上面两个实例既然是并发100个请求,第一个用.all的方式效率就太低了,假如第一组有一个请求非常慢,那会导致9个并发位置的空闲

下面是改进后的代码:

const arr = [];
for (let i = 0; i < 100; i++) {
  arr.push(() => new Promise((resolve) => {
    setTimeout(() => {
      console.log('done', i);
      resolve();
    }, 100 * i);
  }));
}

const parallelRun = () => {
  const runningTask = new Map();
  
  const enqueue = (totalTask, max) => {
    while (runningTask.size < max && totalTask.length) {
      const newTask = totalTask.shift();
      const tempName = totalTask.length;
      runningTask.set(tempName, newTask);
      newTask().finally(() => {
        runningTask.delete(tempName);
        enqueue(totalTask, max);
      });
    }
  }
  
  return enqueue;
};

parallelRun()(arr, 6);
4、借助第三方库实现

在JavaScript中,可以使用Promiseasync/await来控制并发请求的数量。以下是一个示例代码,该代码将限制最大并发请求数为10:

const axios = require('axios');
const semaphore = require('semaphore');

const sem = semaphore(10);
const urls = [/* 你的URL列表 */];

async function fetchUrl(url) {
  await sem.take();
  try {
    const response = await axios.get(url);
    console.log(response.data);
  } catch (error) {
    console.error(error);
  } finally {
    sem.leave();
  }
}

async function fetchAllUrls() {
  await Promise.all(urls.map(fetchUrl));
}

fetchAllUrls();

这个示例使用了semaphore库来创建一个信号量,以限制并发请求的数量。semaphore.take()方法会检查当前是否有可用的许可证,如果有则返回一个Promise,该Promise在许可证被释放时解析。在请求完成之后,使用semaphore.leave()释放许可证,允许其他请求继续进行。

注意:你需要先通过npm安装semaphore库:npm install semaphore

5、借助三方库limit

它是一个第三方库,通常用于管理 Promise 并发。

以下是使用 p-limit 的基本示例:

首先,你需要安装 p-limit。你可以使用 npm(Node Package Manager)来安装:

npm install p-limit

然后,你可以像这样使用 p-limit

const { limit, Promise } = require('p-limit');

// 创建一个限制执行数量的 limit 对象
const limitObj = limit(10);

// 创建一个异步函数,该函数返回一个 Promise
async function asyncFunction(value) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(`Resolving ${value}`);
      resolve(value);
    }, 1000);
  });
}

// 使用 limit 对象来控制并发执行
limitObj.acquire().then(() => {
  asyncFunction('example').then((value) => {
    console.log(`Finished processing ${value}`);
  });
});

在上述代码中,我们创建了一个 limit 对象,该对象限制了同时执行的 Promise 数量。然后我们创建了一个异步函数 asyncFunction,该函数返回一个 Promise。最后,我们使用 limitObj.acquire() 来获取一个可用的 Promise,然后立即执行 asyncFunction。一旦该 Promise 完成,我们就可以继续处理下一个可用的 Promise。

你可能感兴趣的:(我的前端,前端,javascript,开发语言)