实现思路
这是一段 TypeScript 代码,它实现了一个并发控制器。并发控制器是一种用于控制并发任务数量的工具,可以用于限制请求频率等场景。这段代码中,Concurrent 类有一个 peddings 数组,用于存储等待执行的任务。当有新的任务加入时,会调用 append 方法将任务加入到 peddings 数组中,并调用 run 方法执行任务。如果当前并发数量小于总并发数量,则会从 peddings 数组中取出一个任务执行。执行完毕后,会调用 finally 方法将当前并发数量减一,并再次调用 run 方法执行下一个任务。
思维导图
代码实现
/**
* @fileoverview Concurrent.ts
* @description This file contains the Concurrent class.
* @license MIT
* @version 1.0.0
* @since 1.0.0
* @packageDocumentation
* @module Concurrent
* @preferred
* @example
*/
export class Concurrent {
/** 并发数量 */
total = 0;
/** 当前并发数量 */
count = 0;
/** 等待执行任务 */
peddings: (() => Promise<void>)[] = [];
constructor(total: number) {
this.total = total;
}
append(fn: () => Promise<void>) {
this.peddings.push(fn);
this.run();
}
run() {
// 如果没有等待执行的任务,则不执行
if (!this.peddings.length) {
return;
}
// 如果当前并发数量大于等于总并发数量,则不执行
if (this.count >= this.total) {
return;
}
const fn = this.peddings.shift();
if (!fn) {
return;
}
this.count++;
// 执行任务
fn().finally(() => {
this.count--;
this.run();
});
}
}
测试用例
const fn = (item: number, idx: number) => {
return new Promise<void>((resolve: () => void) => {
setTimeout(() => {
const end = new Date().getTime();
console.log(idx, end - start);
resolve();
}, item);
});
};
const cc = new Concurrent(2);
const list = [3000, 1000, 1000, 1000];
const start = new Date().getTime();
list.forEach((item, idx) => cc.append(fn.bind(null, item, idx)));
// 1 1017
// 2 2023
// 0 3004
// 3 3040