当前位置: 首页 > news >正文

【JS】中断和恢复任务序列

前言

封装processTasks函数,实现以下需求

/*** 依次顺序执行一系列任务* 所有任务全部完成后可以得到每个任务的执行结果* 需要返回两个方法,start用于启动任务,pause用于暂停任务* 每个任务具有原子性,即不可中断,只能在两个任务之间中断* @param {...Function} tasks 任务列表,每个任务无参、异步*/
function processTasks(...tasks){}

实现

初步框架如下

function processTasks(...tasks) {const result = []let i = 0 // 当前任务索引let isRunning = false // 是否正在运行return {async start() {isRunning = truewhile (i < tasks.length) {result.push(await tasks[i]())i++if (!isRunning) return // 暂停}},pause() {isRunning = false},}
}

继续改造start的返回,手动控制Promise:

function processTasks(...tasks) {const result = []let i = 0 // 当前任务索引let isRunning = false // 是否正在运行let prom = null // 记录promise结果,防止二次调用start时重复执行之前的任务return {start() {return new Promise(async (resolve, reject) => {if (prom) {// 结束了prom.then(resolve, reject)return}if (isRunning) return // 正在运行,防止多次调用isRunning = truewhile (i < tasks.length) {try {result.push(await tasks[i]())} catch (err) {isRunning = falsereject(err)prom = Promise.reject(err)return // 失败终止}i++if (!isRunning && i < tasks.length - 1) return // 暂停}isRunning = truewhile (i < tasks.length) {try {result.push(await tasks[i]())} catch (err) {isRunning = falsereject(err)prom = Promise.reject(err)return // 失败终止}i++if (!isRunning && i < tasks.length - 1) return // 暂停}// 成功isRunning = falseresolve(result)prom = Promise.resolve(result)})},pause() {isRunning = false},}
}

测试

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./aa.js"></script>
</head><body><button id="start">开始任务</button><button id="pause">暂停任务</button><script>const tasks = []for (let i = 0; i < 5; i++) {tasks.push(() => new Promise(resovle => {setTimeout(() => {resovle(i)}, 2000);}))}const processor = processTasks(...tasks)start.onclick = async () => {console.log("开始任务");const results = await processor.start()console.log("任务执行完成:", results);}pause.onclick = () => {console.log("点击暂停");processor.pause()}</script>
</body></html>

使用场景

大文件分片上传

http://www.lryc.cn/news/426187.html

相关文章:

  • CentOS系统下安装NVIDIA显卡驱动
  • Linux 与 Windows 服务器操作系统 | 全面对比
  • 给既有exe程序添加一机一码验证
  • 【Datawhale X 魔搭 】AI夏令营第四期大模型方向,Task2:头脑风暴会,巧灵脑筋急转弯(持续更新)
  • mysql 多个外键
  • 解决方案上新了丨趋动科技推出基于银河麒麟操作系统的异构算力池化解决方案
  • 14.创建一个实战maven的springboot项目
  • docker部署LNMP
  • 在Spring Boot应用中,如果你希望在访问应用时加上项目的名称或者一个特定的路径前缀
  • 东南大学:Wi-Fi 6搭档全光以太,打造“数智东南”信息高速路
  • C++:stack类(vector和list优缺点、deque)
  • 负载均衡、高可用
  • 从Retrofit支持suspend协程请求说开去
  • 深入浅出:你需要了解的用户数据报协议(UDP)
  • C++的Magic Static
  • vscode添加宏定义
  • Postman接口关联
  • 用Python制作开心消消乐游戏|附源码
  • ArcGIS10.8 安装教程
  • 2024网络安全学习路线,最全保姆级教程,学完直接拿捏!
  • Apache Doris 中Compaction问题分析和典型案例
  • redis面试(十七)MultiLock加锁和释放锁
  • 电脑开机LOGO修改教程_BIOS启动图片替换方法
  • 微前端架构的持续集成与持续部署实践
  • 【STM32 FreeRTOS】事件标志组
  • 【启动centos报错】另一个程序已锁定文件的一部分,进程无法访问,打不开磁盘.
  • 基于YOLOv8-pose的手部关键点检测(3)- 实现实时手部关键点检测
  • kylin系统永久关闭iptables
  • 写一个githubDemo
  • java入门-成员内部类和静态内部类的访问