Promise 控制并发方法

1. Promise.all

Promise.all 用于并行执行多个 Promise,并在所有 Promise 都成功完成时返回一个包含所有结果的数组。如果有任何一个 Promise 失败,Promise.all 会立即拒绝,并返回第一个失败的 Promise 的错误。

const promises = [
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2'),
  fetch('https://api.example.com/data3')
];

Promise.all(promises)
  .then((results) => {
    // results 是一个包含所有成功结果的数组
    console.log(results);
  })
  .catch((error) => {
    // 如果任何一个 Promise 失败,这里会捕获到错误
    console.error(error);
  });

2. Promise.allSettled

Promise.allSettled 用于并行执行多个 Promise,并在所有 Promise 都结算(无论是成功还是失败)时返回一个包含所有结果的数组。每个结果对象包含 status(fulfilled 或 rejected)和相应的 value 或 reason。

const promises = [
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2'),
  fetch('https://api.example.com/data3')
];

Promise.allSettled(promises)
  .then((results) => {
    // results 是一个包含所有结果的数组,每个结果对象包含 status 和 value/reason
    results.forEach((result) => {
      if (result.status === 'fulfilled') {
        console.log(result.value);
      } else {
        console.error(result.reason);
      }
    });
  });

3. Promise.race

Promise.race 用于并行执行多个 Promise,并在第一个 Promise 结算时返回其结果。无论是成功还是失败,Promise.race 都会立即返回第一个结算的 Promise 的结果。

const promises = [
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2'),
  fetch('https://api.example.com/data3')
];

Promise.race(promises)
  .then((result) => {
    // result 是第一个成功完成的 Promise 的结果
    console.log(result);
  })
  .catch((error) => {
    // 如果第一个结算的 Promise 失败,这里会捕获到错误
    console.error(error);
  });

4. 手动控制并发

如果需要更细粒度地控制并发,可以使用 async/await 和 for 循环来手动管理并发数量。例如,限制同时进行的请求数量:

async function fetchWithConcurrency(urls, concurrency) {
  const results = [];
  const pending = [];

  for (const url of urls) {
    const promise = fetch(url).then((response) => response.json());
    results.push(promise);

    if (pending.length >= concurrency) {
      await Promise.race(pending);
    }

    pending.push(promise);

    // 当 promise 结算时,从 pending 数组中移除
    promise.then(() => {
      pending.splice(pending.indexOf(promise), 1);
    });
  }

  return Promise.all(results);
}

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'
];

fetchWithConcurrency(urls, 2)
  .then((results) => {
    console.log(results);
  })
  .catch((error) => {
    console.error(error);
  });

5. 使用第三方库

有些第三方库提供了更高级的并发控制功能,例如 p-limit。

const pLimit = require('p-limit');
const limit = pLimit(2);

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 fetchWithLimit = async (url) => {
  const response = await fetch(url);
  return response.json();
};

const promises = urls.map((url) => limit(() => fetchWithLimit(url)));

Promise.all(promises)
  .then((results) => {
    console.log(results);
  })
  .catch((error) => {
    console.error(error);
  });

总结

Promise.all:并行执行多个 Promise,所有成功时返回结果数组,有一个失败时立即拒绝。

Promise.allSettled:并行执行多个 Promise,所有结算时返回结果数组,包含每个 Promise 的状态和结果。

Promise.race:并行执行多个 Promise,第一个结算时返回其结果。

手动控制并发:使用 async/await 和 for 循环手动管理并发数量。

第三方库:使用如 p-limit 等库来简化并发控制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值