处理高并发, 100 条数据,带宽为 10, 跑满带宽

261 阅读2分钟
// 假设请求的数据存放在一个数组中
const data = [/* ... */];
// 最大并发数
const MAX_CONCURRENT_REQUESTS = 10;

// 定义处理每个数据的异步操作
function processData(item) {
  return new Promise((resolve, reject) => {
    // 发送异步请求,获取数据
    fetch(`https://example.com/api/${item}`).then(response => {
      if (response.ok) {
        // 处理请求成功的情况
        resolve(response.json());
      } else {
        // 处理请求失败的情况
        reject(new Error('请求失败'));
      }
    });
  });
}

// 将多个异步操作分成多个批次处理
function batchProcessData(data) {
  // 使用 slice 方法将数据分成多个批次
  const batches = [];
  for (let i = 0; i < data.length; i += MAX_CONCURRENT_REQUESTS) {
    batches.push(data.slice(i, i + MAX_CONCURRENT_REQUESTS));
  }

  // 使用 map 方法处理每个批次的数据
  return Promise.all(batches.map(batch => {
    // 将每个批次的数据转换成 Promise 数组
    const promises = batch.map(processData);
    // 使用 Promise.allSettled 方法处理 Promise 数组
    return Promise.allSettled(promises);
  })).then(results => {
    // 处理所有异步操作完成后的结果
    const data = [];
    for (const result of results) {
      for (const promiseResult of result.value) {
        if (promiseResult.status === 'fulfilled') {
          data.push(promiseResult.value);
        } else {
          console.error(promiseResult.reason);
        }
      }
    }
    return data;
  }).catch(error => {
    // 处理异步操作中出现的错误
    console.error(error);
  });
}

// 调用函数处理数据
batchProcessData(data).then(results => {
  console.log(results);
});

在上面的代码中,我们使用 slice 方法将数据数组分成多个批次,每个批次最多包含 MAX_CONCURRENT_REQUESTS 个元素。然后使用 map 方法将每个批次的数据转换成 Promise 数组,并使用 Promise.allSettled 方法处理每个批次的 Promise 数组。Promise.allSettled 方法返回一个 Promise,当所有 Promise 都已经完成(不论是 fulfilled 还是 rejected)时,它会返回一个包含每个 Promise 结果的对象数组。在所有异步操作完成后,我们从 Promise.allSettled 返回的结果中提取所有成功的 Promise 结果,并将它们合并成一个数组。如果其中任何一个异步操作失败,则使用 console.error 方法输出错误信息。

通过使用上述代码,我们可以限制并发请求数量,同时仍然可以并行处理多个异步操作。注意,在设置并发请求的最大数量时,应该根据实际情况进行调整,以充分利用带宽资源。