新闻中心

J*aScript Promise并发控制策略

2025-10-26
浏览次数:
返回列表
答案:通过并发控制限制同时执行的异步任务数,可避免资源耗尽。使用Promise队列或async/await实现任务调度,如手动创建任务池或利用p-limit等库控制最大并发,结合Promise.allSettled统一处理结果与错误,平衡性能与稳定性。

javascript promise并发控制策略

在处理大量异步任务时,直接发起全部请求可能导致资源耗尽或服务端限流。这时候需要对 Promise 的并发数量进行控制,避免系统过载。常见的做法是通过“并发控制”机制,让任务按指定数量同时执行,完成一个再启动下一个,从而平滑地处理大量异步操作。

使用 Promise + 队列实现并发控制

核心思路是维护一个任务队列,限制同时运行的 Promise 数量。当某个任务完成后,自动从队列中取出下一个任务执行。

以下是一个简单的并发控制器实现:

function createPool(tasks, concurrency) {
  let index = 0;
  let completed = 0;
  let resolving = false;
  const results = new Array(tasks.length);

  return new Promise((resolve) => {
    function runNext() {
      if (index < tasks.length && !resolving) {
        const currentIndex = index++;
        const task = tasks[currentIndex]();
        task.then(
          (res) => {
            results[currentIndex] = { status: 'fulfilled', value: res };
          },
          (err) => {
            results[currentIndex] = { status: 'rejected', reason: err };
          }
        ).finally(() => {
          completed++;
          if (completed === tasks.length) {
            resolve(results);
          } else {
            runNext();
          }
        });
        // 控制并发数
        for (let i = 1; i < concurrency && index < tasks.length; i++) {
          runNext();
        }
        resolving = true; // 标记已启动初始批次
      }
    }
    runNext();
  });
}

使用方式:

const tasks = Array(10).fill().map((_, i) => () =>
  fetch(`/api/data/${i}`).then(res => res.json())
);

createPool(tasks, 3).then(results => {
  console.log('所有任务完成:', results);
});

基于 async/await 的简化实现

利用 async 函数和数组的 reduce 或递归调用,可以更清晰地管理流程。

示例:逐个执行但保持最大并发数:

async function asyncPool(poolLimit, array, iteratorFn) {
  const ret = [];
  const executing = [];

  for (const item of array) {
    const p = Promise.resolve().then(() => iteratorFn(item));
    ret.push(p);

    if (poolLimit <= array.length) {
      const e = p.finally(() => {
        executing.splice(executing.indexOf(e), 1);
      });
      executing.push(e);

      if (executing.length >= poolLimit) {
        await Promise.race(executing);
      }
    }
  }

  return Promise.allSettled(ret);
}

调用示例:

KPPW客客出品专业威客系统 KPPW客客出品专业威客系统

客客出品专业威客系统英文名称KPPW,也是keke produced professional witkey的缩写。KPPW是一款基于PHP+MYSQL技术构架的威客系统,积客客团队多年实践和对威客模式商业化运作的大量调查分析而精心策划研发,是您轻松搭建威客网站的首选利器。KPPW针对威客任务和商品交易模式进行了细致的分析,提供完善威客任务流程控制解决方案,并将逐步分享威客系统专业化应用作为我们的

KPPW客客出品专业威客系统 0 查看详情 KPPW客客出品专业威客系统
asyncPool(3, [1, 2, 3, 4, 5], (num) =>
  fetch(`/api/${num}`).then(res => res.text())
).then(results => {
  console.log('结果:', results);
});

第三方库方案(如 p-limit)

实际项目中,推荐使用成熟工具库简化开发。例如 p-limit 是一个轻量级的并发控制工具。

安装:

npm install p-limit

使用:

import pLimit from 'p-limit';

const limit = pLimit(3); // 最大并发3

const promises = [
  limit(() => fetch('/api/1').then(res => res.json())),
  limit(() => fetch('/api/2').then(res => res.json())),
  limit(() => fetch('/api/3').then(res => res.json()))
];

Promise.allSettled(promises).then(results => {
  console.log('完成:', results);
});

它内部自动管理队列,语法简洁,适合生产环境。

基本上就这些。手动实现有助于理解原理,但在工程化项目中优先考虑稳定性和可维护性,选择像 p-limit 这样的小而美的工具会更高效。关键是根据业务需求平衡速度与稳定性。不复杂但容易忽略的是错误处理和最终状态收集,建议统一使用 Promise.allSettled 获取完整结果。

以上就是J*aScript Promise并发控制策略的详细内容,更多请关注其它相关文章!


# 如何实现  # 烟台推广营销  # 太原关键词排名提升  # 烟台莱山区网站推广优化  # 汕头seo网络推广方案  # 合肥新站区推广营销口碑  # 虞城网站建设电话号码  # 广西seo的好方法  # 阜新网站建设优化  # seo经典面试题  # 潮州网站建设专家  # 相关文章  # 推荐使用  # 但在  # 的是  # promise  # 如何用  # 回调  # 如何使用  # 是一个  # 递归  # red  # 异步任务  # ai  # 工具  # npm  # json  # js  # java  # javascript 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 拼多多视频播放卡顿如何处理 拼多多视频播放优化技巧  HTML5原生日期选择器与jQuery UI:实现日期选择器的联动与程序化控制  痛风发作了怎么办? 快速止痛和后期饮食调理  如何修改开机登录密码_Windows账户安全设置超详细教程【必学】  漫蛙漫画登录站点 漫蛙2正版漫画快速访问  React列表渲染与独立状态管理:避免全局状态影响局部更新  Excel中VLOOKUP的第四个参数是干什么用的_Excel VLOOKUP第四参数作用解析  俄罗斯方块最新版入口 俄罗斯方块在线玩官网入口  在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明  Log4j Console Appender性能瓶颈与高并发优化策略  《噬血代码2》新预告片发布 展示游戏剧情  学习通网页版官方登录 超星学习通电脑端入口指南  2026年CSGO开箱网站推荐 CSGO开箱平台精选  构建轻量级网站内部消息系统:Formspree 集成指南  NVIDIA股价11月重挫12%:下月有望好转 但难回5万亿美元巅峰  Python自定义类排序:解决lambda键值访问TypeError的实践指南  C++20的source_location是什么_C++在编译期获取源码位置信息用于日志和断言  vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法  支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样  Python多版本共存与虚拟环境管理深度指南  如何在J*a中实现统一对象行为接口_项目大型化时的接口规范化  火狐浏览器占用内存高卡顿怎么办 火狐浏览器性能优化设置技巧  jQuery Mask 插件中实现电话号码固定前导零的教程  Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项  解决深度学习模型训练初期异常高损失与完美验证准确率问题  iwriter统一登录平台 iwrite账号密码登录页面  包子漫画官方网站阅读入口-包子漫画在线漫画官网直达链接  Angular响应式表单:实现提交后表单及按钮的禁用与只读化  《刺客信条4:黑旗》重制版新细节曝光:无缝加载 地图更细致!  J*aScript教程:根据元素文本内容动态设置背景色  c++ dfs和bfs代码 c++深度广度优先搜索算法  CSS实现侧边栏导航项全宽圆角悬停背景效果  漫蛙manwa2最新登录网址_漫蛙manwa2手机网页版入口  微信网页版官方快速登录入口 微信网页版网页版账号直达  Excel如何用迷你图显趋势_Excel用迷你图显趋势【趋势小图】  ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句  优化HTML表单样式:解决输入框焦点跳动与元素间距问题  J*aScript map 迭代中检测空数组元素的有效方法  163邮箱网页版入口导航平台 163邮箱网页版登录入口官网导航  黑猫投诉统一入口官网 消费者权益保护投诉平台  限制HTML日期输入框的日期选择范围  Go语言HTML解析:利用Goquery精准获取指定元素内容  J*aScript数据结构转换:将对象数组按类别分组  Golang如何通过reflect获取匿名字段方法_Golang reflect匿名字段方法访问技巧  Shopware订单对象中获取产品自定义字段的正确方法  台积电1.4nm工艺A14瞄准2028:10年来性能提升80%  Go语言中对Map值调用带指针接收者方法:原理与最佳实践  html5 app怎么运行环境_配html5 app运行环境【教程】  2025-2030年全球乘用车销量预测:新能源成增长主力  为什么简单的XML文件也会解析失败? 检查隐藏的非打印字符(如BOM)的方法 

搜索