JavaScript并发控制:从Promise到队列系统

一、并发控制基础概念

为什么需要并发控制?

当应用同时处理多个异步操作时(如API请求、文件操作等),无限制的并发会导致:

  • 资源耗尽(内存、CPU、网络带宽)
  • 服务端拒绝服务(HTTP 429错误)
  • 级联故障(雪崩效应)
graph LR A[大量并发请求] --> B[资源耗尽] B --> C[服务崩溃] C --> D[级联故障]

JavaScript并发模型

JavaScript使用事件循环(Event Loop)处理并发,但Node.js和浏览器环境有所不同:

环境 并发模型 特点
浏览器 单线程事件循环 每个标签页独立线程
Node.js 多线程+事件循环 Worker Threads处理CPU密集型任务

二、基础并发控制实现

1. Promise.all的并发限制

原生Promise.all无法控制并发数,我们可以实现一个简单的控制版本:

javascript 复制代码
async function promiseAllLimited(tasks, limit) {
    const results = [];
    const executing = new Set();

    for (const task of tasks) {
        // 等待并发数低于限制
        if (executing.size >= limit) {
            await Promise.race(executing);
        }

        const p = task().then(res => {
            executing.delete(p);
            return res;
        });

        executing.add(p);
        results.push(p);
    }

    return Promise.all(results);
}

// 使用示例
const tasks = [];

for (let i = 0; i < 50; i++) {
    tasks.push(() => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(i);
                resolve(i);
            }, 1000 * Math.floor(10 * Math.random()));
        })
    });
}

promiseAllLimited(tasks, 5); // 最大并发5个

2. 基础队列并发控制模型

基础队列并发控制模型,具体的控制队列可以根据自身业务进行扩展,例如添加超时控制,性能监测,任务优先级控制等等

javascript 复制代码
class TaskQueue {
    constructor(concurrency) {
        this.concurrency = concurrency;
        this.running = 0;
        this.queue = [];
    }

    push(task) {
        this.queue.push(task);
        this.next();
    }

    next() {
        while (this.running < this.concurrency && this.queue.length) {
            const task = this.queue.shift();
            task().finally(() => {
                this.running--;
                this.next();
            });
            this.running++;
        }
    }
}

// 使用示例
const queue = new TaskQueue(3);

for (let i = 0; i < 10; i++) {
    queue.push(() => new Promise(resolve => {
        console.log(`任务 ${i} 开始`);
        setTimeout(() => {
            console.log(`任务 ${i} 完成`);
            resolve();
        }, Math.random() * 2000);
    }));
}

结语

如果你喜欢本教程,记得点赞+收藏!关注我获取更多JavaScript开发干货。

相关推荐
Z兽兽1 小时前
React@18+Vite项目配置env文件
前端·react.js·前端框架
SuniaWang1 小时前
《Spring AI + 大模型全栈实战》学习手册系列 · 专题六:《Vue3 前端开发实战:打造企业级 RAG 问答界面》
java·前端·人工智能·spring boot·后端·spring·架构
A_nanda2 小时前
根据AI提示排查vue前端项目
前端·javascript·vue.js
happymaker06262 小时前
web前端学习日记——DAY05(定位、浮动、视频音频播放)
前端·学习·音视频
~无忧花开~2 小时前
React状态管理完全指南
开发语言·前端·javascript·react.js·前端框架
LegendNoTitle3 小时前
计算机三级等级考试 网络技术 选择题考点详细梳理
服务器·前端·经验分享·笔记·php
@大迁世界3 小时前
1.什么是 ReactJS?
前端·javascript·react.js·前端框架·ecmascript
BJ-Giser4 小时前
Cesium 基于EZ-Tree的植被效果
前端·可视化·cesium
王码码20355 小时前
Flutter for OpenHarmony:Flutter 三方库 algoliasearch 毫秒级云端搜索体验(云原生搜索引擎)
android·前端·git·flutter·搜索引擎·云原生·harmonyos
发现一只大呆瓜5 小时前
深入浅出 AST:解密 Vite、Babel编译的底层“黑盒”
前端·面试·vite