天天看点

在 JavaScript 中如何使用Promise控制100个请求并发?

作者:猿习社
“面试时,面试官询问如何通过Promise控制100个请求并发” 该如何回答呢?
在 JavaScript 中如何使用Promise控制100个请求并发?

众所周知,在现代Web开发中,异步已经成为不可或缺的一部分;

当处理大量请求时,如何保持并发是一个非常关键的步骤,Promise异步可以避免代码阻塞一种非常有效的解决方案;

在 JavaScript 中如何使用Promise控制100个请求并发?

今天我们来讨论一下如何使用Promise控制100个请求的并发操作;

在开始之前,我们简单回顾一下Promise的几个关键的基础知识;

Promise 三种状态:

在 JavaScript 中如何使用Promise控制100个请求并发?
  • pending (等待状态)
  • fulfilled (已完成)
  • rejected (已拒绝)

Promise 的几个常用方法:

then

该方法用于指定Promise对象状态变为fulfilled时的回调函数onFulfilled,以及状态变为rejected时的回调函数onRejected。

当Promise对象处于fulfilled状态时,将调用onFulfilled函数,并将Promise的结果值作为参数传递给它。

当Promise对象处于rejected状态时,将调用onRejected函数,并将Promise的拒因(错误信息)作为参数传递给它。

该方法返回一个新的Promise对象,可以通过链式调用then()来进行多个操作。

catch

该方法用于指定Promise对象状态变为rejected时的回调函数onRejected。

它相当于调用then(null, onRejected),用于捕获Promise链中任何一个Promise的拒因。

如果Promise链中任意一个Promise被拒绝,且没有提供对应的错误处理回调函数,则会将错误传递给最近的catch()方法来处理。

finally

该方法用于指定Promise对象状态变为fulfilled或rejected时的回调函数onFinally,无论Promise的状态如何,都会执行该回调函数。

在finally()回调函数中,可以执行一些无论Promise成功还是失败都需要进行的清理操作,比如关闭文件、释放资源等。

finally()回调函数不会修改Promise的状态或结果,它只是在Promise链中传递原始的成功或拒绝值。

race

Promise.race()方法接收一个可迭代对象作为参数,并返回一个新的Promise对象。

当传入的可迭代对象中的任意一个Promise对象状态发生变化,新的Promise对象将立即采用该Promise对象的状态和结果。返回的Promise对象将具有与第一个解决的Promise对象相同的状态和结果。

all

Promise.all()方法接收一个可迭代对象作为参数,并返回一个新的Promise对象。

当传入的可迭代对象中的所有Promise对象都变为fulfilled状态时,新的Promise对象将变为fulfilled状态。

如果传入的可迭代对象中的任意一个Promise对象变为rejected状态,则新的Promise对象将立即变为rejected状态,且其拒因为第一个被拒绝的Promise的拒因。

返回的Promise对象将包含一个数组,数组的顺序与传入的可迭代对象中的Promise对象顺序一致,每个元素是对应Promise对象的结果值。

实现思路

1、将100个请求转换成一个请求数组,每个请求都返回一个promise对象;

2、在每个请求中使用 await 来等待请求结果;

3、控制并发请求数量,用一个计数器来跟踪正在进行请求的数量,在每次发起新的请求之前检查计数器是否已经达到最大并发数;如果没有达到最大并发数,增加计数器,bing发起新请求,否则等待之前的请求完成再发起新请求。

实现步骤:

完整代码如下:

// 并发请求数量
const concurrency = 10;

// 请求函数示例
function fetchData(url) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then(data => resolve(data))
      .catch(error => reject(error));
  });
}

// 并发控制函数
async function requests(urls) {
  const results = [];
  let count = 0;

  // 定义异步处理函数
  async function handleRequest(url) {
    try {
      const result = await fetchData(url);
      return result;
    } catch (error) {
      throw new Error(`Error fetching ${url}: ${error}`);
    }
  }

  // 循环发起请求
  while (urls.length) {
    // 控制并发请求数量
    if (count < concurrency) {
      const url = urls.shift();
      count++;
      results.push(handleRequest(url).finally(() => {
        count--;
      }));
    } else {
      await Promise.race(results);
    }
  }

  // 等待所有请求完成
  await Promise.all(results);

  return results;
}

// 100个请求的URL数组示例,可以根据实际需求修改
const urls = [
  'https://example.com/api/1',
  'https://example.com/api/2',
  'https://example.com/api/4',
  'https://example.com/api/5',
  'https://example.com/api/6',
  // ... 
  'https://example.com/api/100'
];

// 调用并发控制函数
requests(urls)
  .then(results => {
    console.log('所有请求完成', results);
  })
  .catch(error => {
    console.error('请求出错', error);
  });
           

控制100个请求的并发是一个挑战,但借助Promise的特性,我们可以轻松地管理并发性,并获取每个请求的结果。

通过将请求分成小组,并使用Promise.all()进行并发处理,我们可以更高效地处理大量请求。

说明:本文首发头条,欢迎转载!转载请标注来源即可,无需授权!创作不易,喜欢我的文章,记得添加【关注】哦!再次感谢你的支持!

❀ 长按【点赞】会有惊喜哦!❀

~End~

继续阅读