异步代码并发管理

HardWill +0/-0 0 0 正常 2025-12-24T07:01:19 并发控制 · Promise

在现代JavaScript开发中,异步代码并发管理是提升应用性能的关键技能。本文将通过实际案例展示如何有效控制并发数量,避免资源耗尽问题。

并发控制的核心思路

传统的Promise.all()虽然简单直接,但当请求量过大时会导致资源竞争和性能下降。我们可以通过限制同时执行的Promise数量来解决这个问题。

// 基础并发控制实现
function limitConcurrency(tasks, limit) {
  return new Promise((resolve, reject) => {
    if (tasks.length === 0) {
      resolve([]);
      return;
    }
    
    const results = [];
    let index = 0;
    let running = 0;
    let completed = 0;
    
    function run() {
      if (completed >= tasks.length) {
        resolve(results);
        return;
      }
      
      while (running < limit && index < tasks.length) {
        const taskIndex = index++;
        running++;
        
        tasks[taskIndex]()
          .then(result => {
            results[taskIndex] = result;
            completed++;
            running--;
            run(); // 继续执行下一个任务
          })
          .catch(error => {
            reject(error);
          });
      }
    }
    
    run();
  });
}

// 使用示例
const urls = [
  'https://api.example.com/data1',
  'https://api.example.com/data2',
  'https://api.example.com/data3',
  'https://api.example.com/data4',
  'https://api.example.com/data5'
];

const fetchTasks = urls.map(url => () => fetch(url).then(res => res.json()));

limitConcurrency(fetchTasks, 2)
  .then(results => {
    console.log('所有请求完成:', results);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

实际应用场景

在处理大量API请求时,合理控制并发数能有效避免服务器压力过大。比如电商网站的商品详情批量获取场景:

// 商品详情批量获取示例
async function fetchProductDetails(productIds) {
  const limit = 5; // 最大并发数
  
  const tasks = productIds.map(id => async () => {
    try {
      const response = await fetch(`/api/products/${id}`);
      return await response.json();
    } catch (error) {
      console.error(`获取商品 ${id} 失败:`, error);
      return null;
    }
  });
  
  // 使用并发控制
  const results = await limitConcurrency(tasks, limit);
  return results.filter(result => result !== null);
}

// 调用示例
const productIds = Array.from({length: 20}, (_, i) => i + 1);
fetchProductDetails(productIds)
  .then(products => {
    console.log(`成功获取 ${products.length} 个商品详情`);
  });

性能优化建议

  1. 合理设置并发数:根据服务器性能和网络状况调整,通常2-5为宜
  2. 错误处理机制:单个任务失败不应影响其他任务执行
  3. 进度监控:在高并发场景下提供用户反馈

通过以上方法,我们可以在保证用户体验的同时,有效管理异步请求的并发度,避免资源浪费和性能瓶颈。

推广
广告位招租

讨论

0/2000