JavaScript 实现异步任务调度器
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 ms
、500 ms
、300 ms
、400 ms
。
由于并发任务数量最大为2
,最初执行任务1
和2
。任务2
经过500 ms
后执行完毕,输出'2'
。接着执行任务3
,又经过300 ms
后,输出'3'
。任务1
仍然在执行,任务4
开始执行。到了1000 ms
时刻,任务1
执行完毕,输出'1'
。最后任务4
执行完,输出'4'
。
符合并发数量限制,达到了设计要求。
将执行过程表示在时间轴上,如下图所示:
以上是本人学习所得之拙见,若有不妥,欢迎指出交流!
JavaScript 实现异步任务调度器相关推荐
- js实现异步任务调度器
需求: 实现一个异步调度器函数,能够不断的将异步执行的函数加入其中,但是它最多能控制同一时间只能执行3个异步函数,并将执行结果返回. 核心代码: /*** 编写一个异步任务调度器*/ class Sc ...
- 【Netty】 异步任务调度 ( TaskQueue | ScheduleTaskQueue | SocketChannel 管理 )
文章目录 一. 任务队列 TaskQueue 二. 处理器 Handler 同步异步操作 三. 异步任务 ( 用户自定义任务 ) 四. 异步任务 ( 用户自定义定时任务 ) 五. 异步任务 ( 其它线 ...
- 昇腾AI处理器软件栈--任务调度器(TS)
任务调度器与运行管理器工程组成软硬件之间的大坝系统.在执行时,任务调度器对硬件进行任务的驱动,为昇腾AI处理器提供具体的目标任务,与运行管理器一起完成任务调度流程,并将输出数据回送给运行管理器,充当了 ...
- JavaScript:异步执行机制
使用JavaScript的开发者都知道,JS的异步执行机制在JS中占据着重要的地位,主要就是体现在回调函数以及事件方面,最近看了很多文章,将自己的一些感受和理解跟各位分享一下. 前面的博客中也有提到, ...
- html5异步编程,一位前端菜鸟对于JavaScript同步异步编程的了解
来自一个前端菜鸟的对于JavaScript同步异步编程的了解,以下内容,仅供参考.大家知道,JavaScript的执行环境是单线程的,单线程的好处是执行环境简单,不用去考虑诸如资源同步,死锁等多线程阻 ...
- php js 异步上传图片,javascript实现异步图片上传方法实例
如何通过javascript写出异步图片上传?本文我们就和大家分享一些实例代码javascript实现异步图片上传.我们首先看下HTML代码实现的form提交部分.其中大家在测试的时候需要把test的 ...
- 基于单片机的简单的任务调度器
近来工作之余,研究了一下APM的源码. APM源码连接https://pan.baidu.com/s/17Dg1oEJT_fj12DM1BmZWxA 发现源码中有一个简单的任务调度器,不太重要的任务都 ...
- java 分布式任务_一个简单的基于 Redis 的分布式任务调度器 —— Java 语言实现...
折腾了一周的 Java Quartz 集群任务调度,很遗憾没能搞定,网上的相关文章也少得可怜,在多节点(多进程)环境下 Quartz 似乎无法动态增减任务,恼火.无奈之下自己撸了一个简单的任务调度器, ...
- 从零入门 FreeRTOS 操作系统之任务调度器
从零入门 FreeRTOS 操作系统之任务调度器 1 任务调度器的概念 FreeRTOS 中提供的任务调度器是基于优先级的全抢占式调度:在系统中除了中断处理函数.调度器上锁部分的代码和禁止中断的代码是 ...
最新文章
- 递归 尾递归_代码简报:递归,递归,递归
- java 千分位格式话_Java 字符串小数转成千分位格式
- os.path.dirname(path) 返回文件的绝对路径
- 没有统计学基础可以学python-没错!经典教材《统计学习导论》现在有了 Python版!...
- jvm系列(十):如何优化Java GC「译」
- 关于linux下目录树的查看TEEE命令
- android studio gradle 配置copy,Mac系统配置Android Studio的gradle命令
- java 统计图 mysql_java实现各种数据统计图(转)
- RestTemplate的三种使用方式
- java基础输入输出语句
- TW实习日记:第16天
- unity相机围绕模型转_围绕我们的业务模型和风险进行安全测试
- pythontuple_python:tuple 真是鸡肋吗
- 杭州趣链张帅:区块链应用落地,融合产业高速发展
- 如何使用“查找”App 定位丢失的设备或物品?
- Android-path类整理
- HTML编程怎么设置字体,html怎么设置字体
- 合作博弈:联盟、分配和核心core
- VRAY之HDRI材质的应用蓝海创意云
- 西门子博图安装期间反复重启的问题处理
热门文章
- 【springboot】redisTemplate Redis key出现\xac\xed\x00\x05t\x00
- 元宇宙黑马来袭 海姆达尔Heimdallr 开启链游新玩法
- 取消Vue中格式警告
- ncnn param文件及bin模型可视化解析
- php realpath 缓存,PHP的Realpath Cache
- 复旦大学高等代数考试命题的若干经验
- 野心外漏?Windows Defender或将独霸杀毒软件市场?
- java获取指定格式的年月日时分秒时间
- 3个窗口卖票java_三个窗口同时卖火车票,如何用代码将该场景实现?
- Ubuntu安装Samba 服务器