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

 更新时间:2023年04月06日 09:35:19   作者:头疼脑胀的代码搬运工  
这篇文章主要为大家介绍了JS中的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 控制并发量的资料请关注脚本之家其它相关文章!

相关文章

  • JS如何实现一个单文件组件

    JS如何实现一个单文件组件

    这篇文章主要介绍了JS如何实现一个单文件组件,对单文件组件感兴趣的同学,可以参考下
    2021-05-05
  • 用Javascript获取页面元素的具体位置

    用Javascript获取页面元素的具体位置

    制作网页的过程中,你有时候需要知道某个元素在网页上的确切位置,在接下来的文章中为大家介绍下使用js是如何实现的
    2013-12-12
  • javascript动态设置样式style实例分析

    javascript动态设置样式style实例分析

    这篇文章主要介绍了javascript动态设置样式style的方法,实例分析了javascript操作style样式的易错点和相关使用技巧,需要的朋友可以参考下
    2015-05-05
  • Javascript中的解构赋值语法详解

    Javascript中的解构赋值语法详解

    这篇文章主要给大家介绍了关于Javascript中解构赋值语法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • javascript闭包的理解

    javascript闭包的理解

    这篇文章主要介绍了js闭包的相关知识,闭包是Javascript的一个难点,但也是一个很重要的知识点,需要的朋友可以参考下
    2015-04-04
  • Uniapp WebView全屏导致遮挡状态栏的解决方案及注意事项

    Uniapp WebView全屏导致遮挡状态栏的解决方案及注意事项

    这篇文章主要介绍了Uniapp WebView全屏导致遮挡状态栏的解决方案及注意事项,通过动态调整WebView的布局,确保状态栏可见,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-05-05
  • javascript天然的迭代器

    javascript天然的迭代器

    有一个数n=5,不用for循环,怎么返回[1,2,3,4,5]这样一个数组
    2010-10-10
  • 详解JS内存空间

    详解JS内存空间

    因为JavaScript具有自动垃圾回收机制,所以对于前端开发来说,内存空间并不是一个经常被提及的概念。特别是很多不是计算机专业的朋友在进入到前端之后,会对内存空间的认知比较模糊,甚至有些人干脆就是一无所知。为了解决大家的疑惑,本文将详细介绍JS内存空间
    2021-06-06
  • 原生js实现宽度计数器

    原生js实现宽度计数器

    这篇文章主要为大家详细介绍了原生js实现宽度计数器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • javascript算法之数组反转

    javascript算法之数组反转

    这篇文章主要介绍了javascript算法之数组反转,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08

最新评论