控制任务执行顺序、并发数限制、异步任务管理
实现一个支持「并发控制 + 任务队列 + 异步兼容」的轻量调度器类
1. 代码实现
class Scheduler {
/**
* 构造函数
* @param {number} limit - 最大并发数(默认1)
*/
constructor(limit = 1) {
this.limit = limit // 并发限制
this.running = 0 // 正在执行的任务数
this.queue = [] // 任务队列(待执行)
}
/**
* 添加任务到调度器
* @param {Function} task - 任务函数(支持同步/异步,异步需返回Promise)
* @returns {Promise} - 任务执行结果的Promise
*/
add(task) {
return new Promise((resolve, reject) => {
// 将任务和其resolve/reject存入队列
this.queue.push({ task, resolve, reject })
// 尝试执行下一个任务
this.runNext()
})
}
/**
* 执行下一个队列中的任务
*/
runNext() {
// 若当前并发数未达限制,且队列有任务
if (this.running < this.limit && this.queue.length > 0) {
this.running++ // 并发数+1
const { task, resolve, reject } = this.queue.shift() // 取出队列首个任务
try {
// 执行任务(处理同步/异步)
const result = task()
// 若任务返回Promise(异步)
if (result instanceof Promise) {
result
.then((res) => resolve(res))
.catch((err) => reject(err))
.finally(() => {
this.running-- // 并发数-1
this.runNext() // 递归执行下一个任务
})
} else {
// 同步任务直接resolve
resolve(result)
this.running--
this.runNext()
}
} catch (err) {
// 捕获任务执行异常
reject(err)
this.running--
this.runNext()
}
}
}
}
2. 使用示例
// 1. 创建调度器,限制最大并发数为2
const scheduler = new Scheduler(2);
const startTime = Date.now()
// 2. 定义异步任务(模拟接口请求)
const asyncTask = (id, delay) => {
return () =>
new Promise((resolve) => {
setTimeout(() => {
console.log(`时间:${Date.now() - startTime},任务${id}执行完成`);
resolve(id);
}, delay);
});
};
// 3. 添加任务到调度器
scheduler.add(asyncTask(1, 1000)); // 任务1:延迟1000ms
scheduler.add(asyncTask(2, 500)); // 任务2:延迟500ms
scheduler.add(asyncTask(3, 800)); // 任务3:延迟800ms
scheduler.add(asyncTask(4, 300)); // 任务4:延迟300ms
// 执行结果(并发数=2,按队列顺序+完成顺序调度):
// 任务2(500ms)→ 任务1(1000ms)→ 任务4(300ms)→ 任务3(800ms)
// 打印顺序:
// 时间:503,任务2执行完成
// 时间:1001,任务1执行完成
// 时间:1303,任务4执行完成
// 时间:1317,任务3执行完成