三个请求,怎么实现a、b先发送,c最后发送

1,501 阅读2分钟

方案一:使用 Promise.all 控制并发

最直接的方法是使用Promise.all并行处理 A 和 B,待两者都完成后再发送 C。

async function fetchData() {
  try {
    // 同时发送请求A和请求B
    const [resultA, resultB] = await Promise.all([
      fetchRequestA(), // 假设这是你的请求A函数
      fetchRequestB()  // 假设这是你的请求B函数
    ]);
    
    // 请求A和B都完成后,发送请求C
    const resultC = await fetchRequestC(resultA, resultB); // 请求C可能依赖A和B的结果
    
    return resultC;
  } catch (error) {
    console.error('请求失败:', error);
    throw error;
  }
}

优点:实现简单,代码清晰
缺点:如果请求 C 不依赖 A 和 B 的结果,这种方式会增加不必要的等待时间

方案二:手动管理 Promise 并发

如果请求 C 不依赖 A 和 B 的结果,可以让 C 在 A 和 B 开始后立即发送,但在 A 和 B 都完成后再处理 C 的结果。

async function fetchData() {
  try {
    // 立即发送请求A、B、C
    const promiseA = fetchRequestA();
    const promiseB = fetchRequestB();
    const promiseC = fetchRequestC();
    
    // 等待A和B完成(不等待C)
    const [resultA, resultB] = await Promise.all([promiseA, promiseB]);
    
    // 此时A和B已完成,获取C的结果(无论C是否已完成)
    const resultC = await promiseC;
    
    return { resultA, resultB, resultC };
  } catch (error) {
    console.error('请求失败:', error);
    throw error;
  }
}

优点:C 的执行不会被 A 和 B 阻塞,适合 C 不依赖 A、B 结果的场景
缺点:代码复杂度稍高,需要确保 C 的处理逻辑确实不需要 A 和 B 的结果

方案三:使用自定义并发控制器

对于更复杂的并发控制需求,可以封装一个通用的并发控制器。

class RequestController {
  constructor() {
    this.runningCount = 0;
    this.maxConcurrency = 2; // 最大并发数
    this.queue = [];
  }
  
  async addRequest(requestFn) {
    // 如果达到最大并发数,将请求放入队列等待
    if (this.runningCount >= this.maxConcurrency) {
      await new Promise(resolve => this.queue.push(resolve));
    }
    
    this.runningCount++;
    
    try {
      // 执行请求
      const result = await requestFn();
      return result;
    } finally {
      // 请求完成,减少并发计数
      this.runningCount--;
      
      // 如果队列中有等待的请求,取出一个继续执行
      if (this.queue.length > 0) {
        const next = this.queue.shift();
        next();
      }
    }
  }
}

// 使用示例
async function fetchData() {
  const controller = new RequestController();
  
  // 同时发送A和B(受并发数限制)
  const promiseA = controller.addRequest(fetchRequestA);
  const promiseB = controller.addRequest(fetchRequestB);
  
  // 等待A和B完成
  await Promise.all([promiseA, promiseB]);
  
  // 发送请求C
  const resultC = await fetchRequestC();
  
  return resultC;
}

优点:灵活控制并发数,适用于更复杂的场景
缺点:需要额外的代码实现,适合作为工具类复用

选择建议

  • 如果 C 依赖 A 和 B 的结果,推荐方案一
  • 如果 C 不依赖 A 和 B 的结果,但希望 A 和 B 先完成,推荐方案二
  • 如果需要更复杂的并发控制,推荐方案三