建立名词厦门网站快速排名优化
如何实现异步并发限制
文章目录
- 如何实现异步并发限制
- 方法1
- 注意点
- 方法2
- 题目要求
- 实现方法
- 注意点
之前一直没有系统的去总结异步并发限制的实现思路,今天就来做个总结吧
方法1
只有一个变量
pool:代表正在执行中的任务中的集合
function sleep(name, timeOut) {return new Promise(resolve => {console.log(`${name}开始了`);setTimeout(() => {console.log(`${name}结束了`);resolve();}, timeOut);})}const tasks = [() => sleep(1, 1000),() => sleep(2, 2000),() => sleep(3, 3000),() => sleep(5, 6000),() => sleep(8, 8000),];async function parallelLimit(tasks, limit = 2) {// 正在执行中的任务的集合const pool = new Set();for (const task of tasks) {const promise = task();pool.add(promise);promise.then(() => pool.delete(promise));if (pool.size >= limit) {await Promise.race(pool);}}return Promise.all(pool);}parallelLimit(tasks).then(() => {console.log('任务已全部执行');})
注意点
- 此时的 pool 代表的是:正在执行中的任务中的集合
- 使用 Promise.race 这种方式不能保证执行顺序,若要求要按顺序执行,请看第二种方法
方法2
题目要求
要求实现 Scheduler 函数,完成异步并发限制数为2的功能,且需要保证执行顺序
const scheduler = new Scheduler(2);const timeout = (time) =>new Promise((resolve) => {setTimeout(resolve, time);});const addTask = (time, order) => {scheduler.add(() => timeout(time).then(() => console.log(order)))
}addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')// 500ms时,2完成,输出2
// 800ms时,3完成,输出3
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
实现方法
function Scheduler(limit) {// 模拟队列,保存所有任务this.pool = [];// 当前正在执行任务的数目this.count = 0;this.add = function (fn) {this.pool.push(fn);this.run();}this.run = function () {if (this.pool.length && this.count < limit) {const task = this.pool.shift(); // 保证执行顺序this.count++;task().then(() => {this.count--;this.run();})}}
}const scheduler = new Scheduler(2);const timeout = (time) =>new Promise((resolve) => {setTimeout(resolve, time);});const addTask = (time, order) => {scheduler.add(() => timeout(time).then(() => console.log(order)))
}addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')// 500ms时,2完成,输出2
// 800ms时,3完成,输出3
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
注意点
- pool 代表保存所有任务的数组
- count 代表当前正在执行任务的数目
- 保证顺序:需要从数组中顺序取出并执行
两个方法各变量代表的含义不同,实现的思路也就不同,要好好区分两种方法的思想,不然会混淆(像我一样☁️☁️☁️)
道阻且长,面试加油,边复习边查漏补缺吧!!!
passion!!!