如何在 JavaScript 中实现任务队列

任务队列的概念


任务队列就是存放任务的队列,队列中的任务都严格按照进入队列的先后顺序执行。

在前一条任务执行完毕后,立即执行下一条任务,直到任务队列清空。

任务队列的基本执行流程如下:

  • 设置任务队列并发数;

  • 给任务队列添加任务;

  • 当前并发数和最大并发数进行比较,进行任务并发执行;

  • 执行完毕后,判断队列是否为空,如果不为空,则继续执行下一条任务;

  • 直至任务队列清空。

JS代码实现

我们选择使用数组来维护队列的执行顺序,按照“先进先出“的原则,根据最大并发数,依次从数组中取出元素往后执行。

代码实现如下:

class Scheduler {
  constructor(maxCount) {
    this.maxCount = maxCount; // 最大并发量
    this.count = 0; // 当前并发量
    this.taskQueue = []; // 任务队列
  }

  addTask(task) {
    if (this.count < this.maxCount) { // 当前并发量未达到最大并发量
      this.count++; // 并发量+1
      task().then(() => {
        this.count--; // 并发量-1
        this.next(); // 执行下一个任务
      });
    } else {
      this.taskQueue.push(task); // 加入任务队列
    }
  }

  next() {
    if (this.taskQueue.length > 0 && this.count < this.maxCount) {
      this.count++; // 并发量+1
      const task = this.taskQueue.shift();
      task().then(() => {
        this.count--; //并发量-1
        this.next(); //执行下一个任务
      });
    }
  }
}

测试代码

以vue项目为例,分别比较了使用ForEach遍历数组和使用队列遍历数据。

使用forEach遍历数组,控制台输出了数组的全部值。

使用队列遍历数据,控制台根据设置的并发数量逐条输出数组的值。

<template>
  <div>
    <el-button type="primary" @click="forEachData">使用ForEach遍历数组</el-button>
    <el-button type="primary" @click="schedulerforEachData">使用队列遍历数据</el-button>
  </div>
</template>
<script>
import Scheduler from './Scheduler.class.js'
export default {
  name: 'Scheduler',
  data() {
      return {
        data:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
      };
  },
  methods: {
    //使用ForEach遍历数组
    forEachData(){
      console.log("使用ForEach遍历数组")
      this.data.forEach(item=>{
        setTimeout(()=>{
          console.log(item);
        },100);
      });
    },
    // 使用队列遍历数据
    schedulerforEachData(){

      console.log("使用队列遍历数据");
      const scheduler = new Scheduler(1); // 最大并发量为1
      this.data.forEach(item=>{
        scheduler.addTask(() => {
          return this.consoleItem(item)
        });
      });
    },
    // 输出数据
    consoleItem(item){
      return new Promise((resolve, reject)=>{
        // 进行相关操作
        setTimeout(()=>{
          console.log(item);
          resolve(true);
        },100);
      })
    }
  },
}
</script>

执行效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/247547.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎么制作GIF动图?教你这几个简单方法

怎么制作gif动图&#xff1f;GIF动图是一种非常有趣且实用的图片格式&#xff0c;它能够以短小精悍的方式展示动画效果&#xff0c;因此在社交媒体和聊天应用中备受追捧。本文将向您介绍几种制作GIF动图的方法&#xff0c;让您轻松制作出自己的动图。 GIF动图制作方法一&#x…

ubuntu pycharm 死机,如何重启

1. 找出pycharm 进程的id 进入命令行&#xff1a; ps -ef 是查看当前运行的进程 值输入 ps -ef 会返回所有当前执行的进程&#xff0c;太多了&#xff0c;过滤一下&#xff0c;找到 pycharm : ps -ef | grep pycharm 2. 使用 kill -s 9 来杀死进程 如图所是&#xff0c;…

WSL的导出与导入

1需求 现在我需要把我在平板上配好的系统导出来&#xff0c;再放到我的笔记本上。 2基本情况 笔记本电脑没装过wsl 平板上配好了wsl&#xff0c;并且里面的ubuntu配好了python环境。 3从平板导出 比较顺利 先关机。 wsl --shutdown 这里后两个我用不到&#xff0c;因为…

交叉销售与场景业务销售运营

交叉销售 交叉销售的定义 交叉销售是一种从横向角度开发产品市场的方式,是营销人员在完成本职工作以后,主动积极的向现有客户、市场等销售其他的、额外的产品或服务。 交叉销售的类型 补充销售 搭配销售个性化推荐奖励推荐 捆绑销售 交叉销售的意义 通过增加客户的转移成本…

Kafka-客户端使用

理解Kafka正确使用方式 Kafka提供了两套客户端API&#xff0c;HighLevel API和LowLevel API。 HighLevel API封装了kafka的运行细节&#xff0c;使用起来比较简单&#xff0c;是企业开发过程中最常用的客户端API。 LowLevel API则需要客户端自己管理Kafka的运行细节&#xf…

全栈开发中的安全注意事项:最佳实践和工具

安全性是当今数字环境中最重要的问题&#xff0c;而在全栈开发中这一点尤为重要。当企业努力创建强大且动态的应用程序时&#xff0c;他们必须应对复杂的安全威胁领域。在本文中&#xff0c;我们将探讨开发人员可以用来确保安全的全栈开发环境的最佳实践和工具。 1.1 全栈开发的…

YOLOv8原理深度解读,超级详细

整体架构 Backbone&#xff1a; Feature Extractor提取特征的网络&#xff0c;其作用就是提取图片中的信息&#xff0c;供后面的网络使用 Neck &#xff1a; 放在backbone和head之间的&#xff0c;是为了更好的利用backbone提取的特征,起着“特征融合”的作用。 Head&#xf…

金蝶云星空协同开发环境应用内执行SQL脚本

文章目录 金蝶云星空协同开发环境应用内执行SQL脚本 金蝶云星空协同开发环境应用内执行SQL脚本

电阻的运用

本文引注 https://baijiahao.baidu.com/s?id1749115196647029942&wfrspider&forpc 一、零欧电阻 在电子电路设计时经常用到的一种元件就是电阻&#xff0c;我们都知道电阻在电路中起到分压限流的作用。然而&#xff0c;实际使用时会用到一种特殊的电阻&#xff1a;零…

mysql数据恢复

使用MySQL第三方工具binlog2sql binlog2sql&#xff0c;一款基于python开发的开源工具&#xff0c;是由大众点评团队的DBA使用python开发出来的&#xff0c;从MySQL binlog解析出你要的SQL。根据不同选项&#xff0c;你可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。其功…

STM32CubeIDE串口空闲中断实现不定长数据接收

STM32F051空闲中断实现串口不定长数据接收 目的编程软件配置串口开中断中断程序 运行结果碰到的问题 目的 在串口输入不定长数据时&#xff0c;通过串口空闲中断来断帧接收数据。 编程软件 STM32CubeIDE STM32CubeMX配置MCU。通过对端口配置&#xff0c;自动生成程序&#x…

AI抽烟识别系统研发关键

为了设计一个有效的AI抽烟识别系统&#xff0c;我们需要考虑几个关键组成部分&#xff1a;图像捕捉、数据处理、模型训练、以及实际应用场景。下面是这个方案的详细阐述&#xff1a; 1. 图像捕捉与数据收集 摄像头部署&#xff1a;首先&#xff0c;在需要监控的区域安装高分辨…

springboot自定义starter步骤

引入相关依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional> </dependency><dependency><groupId>org.pro…

SpringBoot基础使用及对其他项目进行整合

目录 一、简介 1-讲述 2-特点 二、创建配置 1.创建 2.配置 3.代码生成 三、项目整合 每篇一获 一、简介 1-讲述 众所周知 Spring 应用需要进行大量的配置&#xff0c;各种 XML 配置和注解配置让人眼花缭乱&#xff0c;且极容易出错&#xff0c;因此 Spring 一度被称…

Ignoring query to other database

登录数据库执行查看database的脚本提示 仔细观察才发现&#xff0c;登录的时候我写的是&#xff0c;没写 -u 退出重新登录&#xff0c;好了~

继续看回溯问题

关卡名 继续看回溯问题 我会了✔️ 内容 1.复习递归和N叉树&#xff0c;理解相关代码是如何实现的 ✔️ 2.理解回溯到底怎么回事 ✔️ 3.掌握如何使用回溯来解决二叉树的路径问题 ✔️ 1 复原IP地址 这也是一个经典的分割类型的回溯问题。LeetCode93.有效IP地址正好由四…

垃圾回收 (GC) 在 .NET Core 中是如何工作的?(二)

接上一篇文章垃圾回收 (GC) 在 .NET Core 中是如何工作的&#xff1f;-CSDN博客 GC 会分配堆段&#xff0c;其中每个段都是一系列连续的内存。 置于堆中的对象归类为 3 个代系之一&#xff1a;0、1 或 2。 代系可确定 GC 尝试在应用不再引用的托管对象上释放内存的频率。 编号…

C++_构造函数与析构函数

目录 1、构造函数的写法 1.2 构造函数优化写法 2、默认构造函数与默认成员函数 2.1 默认成员函数对不同类型的处理 3、对内置类型的补丁 4、析构函数 4.1 析构函数的写法 5、默认析构函数 6、初始化列表 6.1 初始化列表的写法 6.2 初始化列表的作用 6.3 回顾与总结 …

引迈信息-JNPF平台怎么样?值得入手吗?

目录 1.前言 2.引迈低代码怎么样&#xff1f; 3.平台亮点展示 4.引迈产品特点 5.引迈产品技术栈&#xff1a; 1.前言 低代码是近几年比较火的一种应用程序快速开发方式&#xff0c;它能帮助用户在开发软件的过程中大幅减少手工编码量&#xff0c;并通过可视化组件加速应用…

高效电商策略:小红书集成CRM与广告推广无代码化

无代码开发的优势 随着科技的不断进步&#xff0c;无代码开发&#xff08;No-Code Development&#xff09;已经成为快速构建系统和应用的新趋势。无代码开发指的是不需要传统编程知识&#xff0c;通过图形化的用户界面和模型驱动逻辑来创建应用程序。这种方式让非技术背景的用…