深入理解JS中的Promise.race控制并发量

目录
  • 开篇
    • 一、Promise.race
    • 二、并发效果展示
    • 三、代码
  • 总结与思考

开篇

比如在开发中会进行一系列的网络请求,但是有些情况需要控制一下网络请求请并发量。这里简单的用 Promise.raceawait 的特性来理解一下,如何对任务的并发量进行控制。

一、Promise.race

Promise.race 作用就是将多个异步任务包裹起来,当有一个完成的话,那么就会触发 then 事件。除了这个不错的特性方法外,await 这个关键字也比较有用,可以这样理解,await 后面的代码其实就相当于在 Promisethen 事件,即:如果异步任务没有完成的话,await 后面的逻辑是不会执行的,可以联想一下 generator 生成器里面的 yield 它能直接控制方法体里面的代码执行跟暂停,外界由一个迭代器 next 方法进行操控。

await 虽然好用,也只是在一个“异步”方法里需要“同步执行”的时候。then 的异步回调,其实也有它的用处。可以将完全不关心的事务放到里面,由它去执行到最后的结果。

二、并发效果展示

三、代码

class ConcurrencyTask {
    // 回调
    callBack = ()=>{}
    // 任务
    task = ()=>{}
    // 异步任务
    promse = null
    constructor(task,callBack){
        this.task = task
        this.callBack = callBack
    }
    // 开始进行任务
    beginExecuteTask(){
        this.promse = new Promise((resolve, reject)=>{
            this.task(resolve,reject)
        })
        return this.promse
    }
    // 类方法初始化
    static SimulationTask(time){
        return new ConcurrencyTask((resolve, _)=>{
                console.log('开始执行延时任务:' + (time / 1000) + '秒!')
                setTimeout(()=>{
                    resolve('延时任务完成:' + (time / 1000) + '秒!')
                },time)
            },(res)=>{
                console.log(res)
        })
    }
}
class ConcurrencyQueue {
    // 最大并发数
    maxConcurrencyNum = 1
    // 并发任务集合
    concurrencyTasks = []
    // 正在进行的任务
    executionTasks = []
    constructor(maxConcurrencyNum,...concurrencyTasks){
        this.maxConcurrencyNum = maxConcurrencyNum
        concurrencyTasks.forEach((task)=>{
            this.concurrencyTasks.push(task)
        })
    }
    // 开始执行
    async beginExecuteTasks(){
        // 当前执行任务
        this.executionTasks = []
        // 全部任务
        let allExecutionTasks = []
        for(let index = 0;index < this.concurrencyTasks.length;index ++){
            let task = this.concurrencyTasks[index]
            // 开始并进行后续追踪
            task.beginExecuteTask().then((res)=>{
                this.executionTasks.splice(this.executionTasks.indexOf(task),1)
                if(task.callBack){
                    task.callBack(res)
                }
            })
            // 不足直接添加
            if(this.executionTasks.length < this.maxConcurrencyNum){
                //待执行任务集合添加
                this.executionTasks.push(task)
                //全任务执行集合添加
                allExecutionTasks.push(task)
                if((this.concurrencyTasks.length - 1) == index || this.executionTasks.length >= this.maxConcurrencyNum){
                    // 满足直接运行
                    await Promise.race(this.executionTasks.map((task)=>{ return task.promse }))
                }
            }
        }
        //全部任务完成
        await Promise.all(allExecutionTasks.map((task)=>{ return task.promse }))
        console.log('任务全部完成')
    }
}
export { ConcurrencyTask ,ConcurrencyQueue }

ESM 模式导入,需要 node 简单起一个服务

<script type="module">
    import { ConcurrencyTask ,ConcurrencyQueue } from "./concurrencyTask.js"
    //添加任务
    let concurrencyQueue = new ConcurrencyQueue(3,ConcurrencyTask.SimulationTask(1000),ConcurrencyTask.SimulationTask(6000),ConcurrencyTask.SimulationTask(5000),ConcurrencyTask.SimulationTask(4000),ConcurrencyTask.SimulationTask(2000),ConcurrencyTask.SimulationTask(3000))
    //开始执行任务
    concurrencyQueue.beginExecuteTasks()
</script>

总结与思考

如果知识点不能结合应用场景,那么,它其实没有什么需要记忆的必要性。

以上就是深入理解JS中的Promise.race控制并发量的详细内容,更多关于JS Promise.race 控制并发量的资料请关注我们其它相关文章!

(0)

相关推荐

  • js Promise并发控制数量的方法

    目录 问题 背景 思路 & 实现 问题 要求写一个方法控制 Promise 并发数量,如下: promiseConcurrencyLimit(limit, array, iteratorFn) limit 是同一时间执行的 promise 数量,array 是参数数组,iteratorFn 每个 promise 中执行的异步操作. 背景 开发中需要在多个promise处理完成后执行后置逻辑,通常使用Promise.all: Primise.all([p1, p2, p3]).then((res)

  • JavaScript使用Promise实现并发请求数限制

    目录 没有Promise的并发请求 使用Promise限制并发请求 使用Promise实现并发请求数限制 总结 没有Promise的并发请求 在Web开发中,我们经常需要发起多个异步请求来获取数据.例如,我们可能需要从服务器获取一些用户信息.文章内容.评论列表等等.如果我们使用的是传统的JavaScript回调函数,可能会写出类似下面这样的代码: function getUsers(callback) { fetch('https://example.com/users', (response)

  • JavaScript如何利用Promise控制并发请求个数

    一.场景 假设现在有这么一种场景:现有 30 个异步请求需要发送,但由于某些原因,我们必须将同一时刻并发请求数量控制在 5 个以内,同时还要尽可能快速的拿到响应结果. 如图所示: 上图这样的排队和并发请求的场景基本类似,窗口只有三个,人超过三个之后,后面的人只能排队了. 二.串行和并行 串行:一个异步请求完了之后在进行下一个请求 并行:多个异步请求同时进行 串行举例: var p = function () { return new Promise(function (resolve, reje

  • 深入理解JS中的Promise.race控制并发量

    目录 开篇 一.Promise.race 二.并发效果展示 三.代码 总结与思考 开篇 比如在开发中会进行一系列的网络请求,但是有些情况需要控制一下网络请求请并发量.这里简单的用 Promise.race 及 await 的特性来理解一下,如何对任务的并发量进行控制. 一.Promise.race Promise.race 作用就是将多个异步任务包裹起来,当有一个完成的话,那么就会触发 then 事件.除了这个不错的特性方法外,await 这个关键字也比较有用,可以这样理解,await 后面的代

  • JS 中使用Promise 实现红绿灯实例代码(demo)

    要求 使用promise 实现红绿灯颜色的跳转 绿灯执行三秒后 黄灯执行四秒后 红灯执行五秒 html 实现如下: <ul id="traffic" class=""> <li id="green"></li> <li id="yellow"></li> <li id="red"></li> </ul> 定义一个

  • 深入理解js中this的用法

    this是js的一个关键字,随着函数使用场合不同,this的值会发生变化.但是总有一个原则,那就是this指的是调用函数的那个对象. 1.纯粹函数调用. function test() { this.x = 1; alert(x); } test(); 其实这里的this就是全局变量.看下面的例子就能很好的理解其实this就是全局对象Global.其实这里的this就是全局变量.看下面的例子就能很好的理解其实this就是全局对象Global. var x = 1; function test()

  • 深入理解JS中的substr和substring

    substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参数 stringvar 必选项.要提取子字符串的字符串文字或 String 对象. start 必选项.所需的子字符串的起始位置.字符串中的第一个字符的索引为 0. length 可选项.在返回的子字符串中应包括的字符个数. 说明 如果 length 为 0 或负数,将返回一个空字符串.如果没有指定该参数,则子字符串将延续到 stringvar 的最后. 示

  • 深入理解JS中Number(),parseInt(),parseFloat()三者比较

    参考阅读: 详解js中Number().parseInt()和parseFloat()的区别 详解JS转换数值函数Number().parseInt().parseFloat() 在项目开发中我们经常会用到转型方法,尤其是JS这种松散型的语言.其中比较常用的方法就是Number()方法和ParseInt()/ParseFloat()方法了,下面我们分别对这几种方法的转型机制进行详细地说明.具体内容详情如下所示: [正文内容] Number() --------------------------

  • 原生js中运算符及流程控制示例详解

    运算符 算数:+ 加.- 减.* 乘./ 除.% 求模 赋值:=.+=.-=.*=./=.%= 关系:>.<. >=. <=. ==. ===. !=. !== 逻辑:||或.&&与.!否 实例1.求模 window.onload = function(){ alert(0%2) //0 alert(1%2) //1 alert(2%2) //0 } 实例2.隔行变色 <body> <ol> <li>取模:就是求余数</li

  • 深入理解JS中attribute和property的区别

    目录 attribute和property介绍 “脚踏两只船” attribute和property的取值和赋值 1.attribute取值 2.attribute赋值 3.property取值 4.Property赋值 更改property和attribute其中一个值,会出现什么结果 property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴. property是DOM中

  • GO中sync包自由控制并发示例详解

    目录 资源竞争 sync.Mutex sync.RWMutex sync.WaitGroup sync.Once sync.Cond 资源竞争 channel 常用于并发通信,要保证并发安全,主要使用互斥锁.在并发的过程中,当一个内存被多个 goroutine 同时访问时,就会产生资源竞争的情况.这块内存也可以称为共享资源. 并发时对于共享资源必然会出现抢占资源的情况,如果是对某资源的统计,很可能就会导致结果错误.为保证只有一个协程拿到资源并操作它,可以引入互斥锁 sync.Mutex. syn

  • 深入理解JS异步编程-Promise

    前言 "JS 是基于单线程事件循环"的概念构建的,回调函数不会立即执行,由事件轮询去检测事件是否执行完毕,当执行完有结果后,将结果放入回调函数的参数中,然后将回调函数添加到事件队列中等待被执行. 同时也讲了回调函数的问题: 一是"回调地狱",因为异步回调函数的特点:回调函数是作为异步函数的参数,一层一层嵌套,当嵌套过多,将使代码逻辑变得混乱,也无法做好错误捕捉和处理(只能在回调函数内部 try catch). 二是回调的执行方式不符合自然语言的线性思维方式,不容易被

  • 深入理解js 中async 函数的含义和用法

    一.终极解决 异步操作是 JavaScript 编程的麻烦事,麻烦到一直有人提出各种各样的方案,试图解决这个问题. 从最早的回调函数,到 Promise 对象,再到 Generator 函数,每次都有所改进,但又让人觉得不彻底.它们都有额外的复杂性,都需要理解抽象的底层运行机制. 异步I/O不就是读取一个文件吗,干嘛要搞得这么复杂?异步编程的最高境界,就是根本不用关心它是不是异步. async 函数就是隧道尽头的亮光,很多人认为它是异步操作的终极解决方案. 二.async 函数是什么? 一句话,

随机推荐