用Promise实现前端并发请求

javascript 复制代码
/**
* 构造假请求
*/
async function request(url) {
  return new Promise((resolve) => {
    setTimeout(
      () => {
        resolve(url);
      },
      // Math.random() * 500 + 800,
      1000,
    );
  });
}

请求一次,查看耗时,预计应该是1s:

javascript 复制代码
async function requestOnce() {
  const t1 = Date.now();
  const res = await request(1);
  console.log('一次请求耗时=', Date.now() - t1, 'ms,请求结果=', res);
}
requestOnce();

结果:

12个数据发起并行请求,预计耗时1s:

javascript 复制代码
async function requestAsync() {
  const t2 = Date.now();
  const requests = new Array(12).fill(2).map(request);
  const res2 = await Promise.all(requests);
  console.log('批量请求耗时=', Date.now() - t2, 'ms,请求结果=', res2, ',预计是 1000 ms');
}

requestAsync();

结果:

12个请求并发进行,但限制最多3个请求可并发,预计耗时4s:

javascript 复制代码
async function concurrencyRequest(urls, maxNum) {
  const buffer = [];//并发请求池,最多有maxNum个
  const t3 = Date.now();
  const res = [];
  for (let i = 0; i < urls.length && buffer.length < maxNum; ++i) {
    // console.log('next=', i);
    const promise = new Promise((resolve) => request(urls[i]).then(resolve));
    buffer.push(promise);
    promise
      .then((response) => (res[i] = response))
      .finally(() => {//每个请求完成后都从buffer中删除并保存响应
        const index = buffer.findIndex((item) => item === promise);
        buffer.splice(index, 1);
        // console.log('删除一个promise', buffer.length);
      });
    if (buffer.length === maxNum) {//必须等待buffer size小于maxNum才能继续请求
      await Promise.race(buffer);
    }
  }
  await Promise.all(buffer);//需要等待最后剩下的几个请求完成才算完成
  console.log('并发请求耗时=', Date.now() - t3, '请求结果=', res, '预计时间是 4000 ms');
}

concurrencyRequest(
  new Array(12).fill(1).map((_, i) => i + 1),
  3,
);
相关推荐
白帽攻防录3 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛4 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_965148114 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
lpfasd1234 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
xixiaoyunya5 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
学逆向的5 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全
小坏讲微服务5 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
Data analyse4567 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
xiaogai_gai7 小时前
金蝶收料通知单查询策略实战教程:从源系统拉取到中间层落地的完整路径
java·前端·数据库
打工仔折腾 AI7 小时前
用 Dashlet 把极空间 NAS 服务入口整理成统一导航首页的实践
java·开发语言·人工智能·后端·python·rpc·ai agent 实战