1. 题目要求

最近遇到了一个 JavaScript 手写代码题,要求实现一个具有并发数量限制的异步任务调度器,可以规定最大同时运行的任务。

实现一个Scheduler类,使下面的代码能正确输出。

// 延迟函数
const sleep = time => new Promise(resolve => setTimeout(resolve, time));// 同时进行的任务最多2个
const scheduler = new Scheduler(2);// 添加异步任务
// time: 任务执行的时间
// val: 参数
const addTask = (time, val) => {scheduler.add(() => {return sleep(time).then(() => console.log(val));});
};addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');
// 2
// 3
// 1
// 4

2. 思路及实现

设计Scheduler类,要具有并发数量限制功能,需要定义最大可并发任务数max,从入参中获取。并定义当前并发任务数count,表示正在执行的任务数量。另外,定义一个待执行的任务队列queue

在添加任务add函数中,首先判断当前正在执行的任务数,若当前正在执行的任务数达到最大容量max,则当前的任务需要阻塞在此处。具体做法为,new一个Promise对象,将resolve函数的引用推入队列queue中。只要resolve函数没有被执行,当前任务就会一直阻塞在这里。

若当前正在执行的任务数没有达到最大容量,那么对count进行加一,执行当前函数fn,并拿到返回值res,执行完毕后count减一。此时若队列queue中有值,说明之前有任务因为并发数量限制而被阻塞,将队头的resolve弹出,并执行。执行resolve之后,之前阻塞的任务就可以正常执行了。

最后返回fn函数执行的结果res

具体代码如下:

class Scheduler {constructor(max) {// 最大可并发任务数this.max = max;// 当前并发任务数this.count = 0;// 阻塞的任务队列this.queue = [];}async add(fn) {if (this.count >= this.max) {// 若当前正在执行的任务,达到最大容量max// 阻塞在此处,等待前面的任务执行完毕后将resolve弹出并执行await new Promise(resolve => this.queue.push(resolve));}// 当前并发任务数++this.count++;// 使用await执行此函数const res = await fn();// 执行完毕,当前并发任务数--this.count--;// 若队列中有值,将其resolve弹出,并执行// 以便阻塞的任务,可以正常执行this.queue.length && this.queue.shift()();// 返回函数执行的结果return res;}
}

3. 测试

class Scheduler {...
}const sleep = time => new Promise(resolve => setTimeout(resolve, time));const scheduler = new Scheduler(2);const addTask = (time, val) => {scheduler.add(() => {return sleep(time).then(() => console.log(val));});
};addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');
// 2
// 3
// 1
// 4

如上代码所示,并发任务数量最大为2。添加了4个异步任务,所需要执行的时间分别为1000 ms500 ms300 ms400 ms

由于并发任务数量最大为2,最初执行任务12。任务2经过500 ms后执行完毕,输出'2'。接着执行任务3,又经过300 ms后,输出'3'。任务1仍然在执行,任务4开始执行。到了1000 ms时刻,任务1执行完毕,输出'1'。最后任务4执行完,输出'4'

符合并发数量限制,达到了设计要求。

将执行过程表示在时间轴上,如下图所示:


以上是本人学习所得之拙见,若有不妥,欢迎指出交流!


JavaScript 实现异步任务调度器相关推荐

  1. js实现异步任务调度器

    需求: 实现一个异步调度器函数,能够不断的将异步执行的函数加入其中,但是它最多能控制同一时间只能执行3个异步函数,并将执行结果返回. 核心代码: /*** 编写一个异步任务调度器*/ class Sc ...

  2. 【Netty】 异步任务调度 ( TaskQueue | ScheduleTaskQueue | SocketChannel 管理 )

    文章目录 一. 任务队列 TaskQueue 二. 处理器 Handler 同步异步操作 三. 异步任务 ( 用户自定义任务 ) 四. 异步任务 ( 用户自定义定时任务 ) 五. 异步任务 ( 其它线 ...

  3. 昇腾AI处理器软件栈--任务调度器(TS)

    任务调度器与运行管理器工程组成软硬件之间的大坝系统.在执行时,任务调度器对硬件进行任务的驱动,为昇腾AI处理器提供具体的目标任务,与运行管理器一起完成任务调度流程,并将输出数据回送给运行管理器,充当了 ...

  4. JavaScript:异步执行机制

    使用JavaScript的开发者都知道,JS的异步执行机制在JS中占据着重要的地位,主要就是体现在回调函数以及事件方面,最近看了很多文章,将自己的一些感受和理解跟各位分享一下. 前面的博客中也有提到, ...

  5. html5异步编程,一位前端菜鸟对于JavaScript同步异步编程的了解

    来自一个前端菜鸟的对于JavaScript同步异步编程的了解,以下内容,仅供参考.大家知道,JavaScript的执行环境是单线程的,单线程的好处是执行环境简单,不用去考虑诸如资源同步,死锁等多线程阻 ...

  6. php js 异步上传图片,javascript实现异步图片上传方法实例

    如何通过javascript写出异步图片上传?本文我们就和大家分享一些实例代码javascript实现异步图片上传.我们首先看下HTML代码实现的form提交部分.其中大家在测试的时候需要把test的 ...

  7. 基于单片机的简单的任务调度器

    近来工作之余,研究了一下APM的源码. APM源码连接https://pan.baidu.com/s/17Dg1oEJT_fj12DM1BmZWxA 发现源码中有一个简单的任务调度器,不太重要的任务都 ...

  8. java 分布式任务_一个简单的基于 Redis 的分布式任务调度器 —— Java 语言实现...

    折腾了一周的 Java Quartz 集群任务调度,很遗憾没能搞定,网上的相关文章也少得可怜,在多节点(多进程)环境下 Quartz 似乎无法动态增减任务,恼火.无奈之下自己撸了一个简单的任务调度器, ...

  9. 从零入门 FreeRTOS 操作系统之任务调度器

    从零入门 FreeRTOS 操作系统之任务调度器 1 任务调度器的概念 FreeRTOS 中提供的任务调度器是基于优先级的全抢占式调度:在系统中除了中断处理函数.调度器上锁部分的代码和禁止中断的代码是 ...

最新文章

  1. 递归 尾递归_代码简报:递归,递归,递归
  2. java 千分位格式话_Java 字符串小数转成千分位格式
  3. os.path.dirname(path) 返回文件的绝对路径
  4. 没有统计学基础可以学python-没错!经典教材《统计学习导论》现在有了 Python版!...
  5. jvm系列(十):如何优化Java GC「译」
  6. 关于linux下目录树的查看TEEE命令
  7. android studio gradle 配置copy,Mac系统配置Android Studio的gradle命令
  8. java 统计图 mysql_java实现各种数据统计图(转)
  9. RestTemplate的三种使用方式
  10. java基础输入输出语句
  11. TW实习日记:第16天
  12. unity相机围绕模型转_围绕我们的业务模型和风险进行安全测试
  13. pythontuple_python:tuple 真是鸡肋吗
  14. 杭州趣链张帅:区块链应用落地,融合产业高速发展
  15. 如何使用“查找”App 定位丢失的设备或物品?
  16. Android-path类整理
  17. HTML编程怎么设置字体,html怎么设置字体
  18. 合作博弈:联盟、分配和核心core
  19. VRAY之HDRI材质的应用蓝海创意云
  20. 西门子博图安装期间反复重启的问题处理

热门文章

  1. 【springboot】redisTemplate Redis key出现\xac\xed\x00\x05t\x00
  2. 元宇宙黑马来袭 海姆达尔Heimdallr 开启链游新玩法
  3. 取消Vue中格式警告
  4. ncnn param文件及bin模型可视化解析
  5. php realpath 缓存,PHP的Realpath Cache
  6. 复旦大学高等代数考试命题的若干经验
  7. 野心外漏?Windows Defender或将独霸杀毒软件市场?
  8. java获取指定格式的年月日时分秒时间
  9. 3个窗口卖票java_三个窗口同时卖火车票,如何用代码将该场景实现?
  10. Ubuntu安装Samba 服务器