JavaScript实现带并发限制的异步调度器
本文详解如何在JavaScript中实现一个带并发限制的异步调度器。通过维护任务队列并利用Promise.race机制,确保同时运行的任务不超过指定数量(如两个)。文章分析了任务进入、执行、完成及新任务接替的完整流程,提供了核心代码逻辑与测试用例,帮助开发者掌握控制异步执行顺序与并发的技巧。
题目描述与需求分析
题目描述
使用JavaScript实现一个具有并发限制功能的异步调度器scheduler,核心要求是保证在同一时刻运行的任务数量最多为两个。
假设当前有4个任务需要执行,它们的完成时间分别为1000ms、500ms、300ms和400ms。
在该调度器的控制下,任务的完成输出顺序应为2、3、1、4。
由于任务1和2已入队,任务2完成后输出2,任务3进入;任务3完成后输出3,耗时800ms;任务4在200ms后进入,随后任务1完成输出1,最后任务4完成输出4。
实现的核心目标是严格限制最多有两个任务同时处于运行状态。
代码的调用模板大致结构如下:
class Scheduler{
add(promiseCreator){.....}
}
// 设置一个以每time秒执行异步任务的定时器
const timeout = (time) => {
new Promise(resolve => {
setTimeout(resolve,time)
})
}
// 实例
const scheduler = new Scheduler()
const addTask = (time,order)=>{
scheduler.add(()=>{ //调用实例的方法
timeout(time) //每time秒执行一下任务(其实每一秒就行->time=1000ms即可)
})
}调度器核心逻辑解析
首先对题目进行逻辑分析,初看可能感到困惑,但理清思路后并不复杂。
通俗来说,这是一个只能同时执行两个任务的队列系统,任务按照设定的时间间隔依次进入队列执行。
由于同时运行的任务数不能超过两个,因此每次启动一个新任务时,将其加入数组或队列中。判断当前运行中的任务数量是否小于2,如果大于0且小于2,则立即执行该Promise函数。
当队列中已有两个任务在运行时,如何处理新任务?需要对Promise函数进行选型,普通的Promise.then无法满足“谁先完成谁释放槽位”的需求。在这两个同时运行的任务中,需要有一个先后判断机制,即哪个任务先执行完毕,就由它来触发下一个任务的执行。这种竞争关系适合使用Promise.race来实现。(注:这体现了任务间的并发竞争机制。)
确认一种情况:当队列中只有一个任务在运行时,只需正常执行该任务,并在执行完毕后从队列中移除即可。
但当运行任务数达到两个时,就需要进行判断。只要队列中正在运行的任务数量等于或大于2,就要通过Promise.race来竞争执行结果。一旦race结束(即其中一个任务完成),在finally块中调用add方法,将下一个Promise任务加入队列继续执行。
代码实现与测试验证
理清上述逻辑后,即可开始编写代码。
class Scheduler{
queue = new Set<Promise<any>>() //去重的promise队列~
add(promiseCreator:()=>Promose<any>){ //每次用来加任务的方法~~
if(this.queue.size>0 && this.queue.size<2){
const promise = promiseCreator()
this.queue.add(promise)
promise.finally(()=>{
this.queue.delete(promise)
})
return promise
}
// 只要到了2个任务 就开始race这俩任务
// race出个结果再继续放下一个(doge)卷起来
const queueArr = []
this.queue.forEach(item => queueArr.push(item)) // 放进数组中~
return Promise.race(queueArr).finally(this.add(promiseCreator))
}
}最后,通过调用示例来验证结果是否正确。
addTask(1000,1) addTask(500,2) addTask(300,3) addTask(400,4)
检查输出顺序是否为2、3、1、4。
到此关于基于JS实现带并发限制的异步调度器的介绍结束,更多相关JS异步调度器内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
