JavaScript实现控制并发请求数量的方法详解

 更新时间:2024年02月05日 14:33:44   作者:黑土豆  
这篇文章主要为大家详细介绍了JavaScript如何实现控制并发请求数量,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

前言

嗨呀,又是将近一个月没有更文了,想死你们了!今天又来继续我的更文事业,技术的道路注定是要将卷进行到底的!至于这么久才来更文的原因,那自然是没有好的羊毛值得去薅,一旦有好羊毛那当然是也不会缺席的,所以今天我来了!

这次要分享的主题就是前久饭后在和同事讨论时无意间发现的,那就是前端如何实现并发请求数量控制。如果你在实际项目中有过类似的需求,应该不会陌生,反之如果你还没有且还不了解的话,那你就有必要耐心地看完这篇文章,保证你一定会有所收获的!

场景

假设有这么一个场景:现在有20个异步请求需要发送,但是由于某些原因,要求我们必须将同一时刻的并发请求数量控制在3个以内,并且还要尽可能快速的拿到响应结果。其实这个场景在一些大厂的面试题中也有过提及,如下:

实现一个并发请求函数concurrencyRequest(urls, maxNum),要求如下:

• 要求最大并发数 maxNum

• 每当有一个请求返回,就留下一个空位,可以增加新的请求

• 所有请求完成后,结果按照 urls 里面的顺序依次打出(发送请求的函数可以直接使用fetch即可)

遇到到这个问题时你会怎么来做?

遇到这个问题还是先来分析一下这个问题的设计思路→。

设计思路

首先来看将上面的文字转化为图之后的效果:

这样就直观的看到,有一个最大并发数maxNum20个异步请求的urls集合和并发返回之后的results集合。

下面就开始演示这个思路是如何开始的,如下:

首先按照每次只能并发3个请求的要求,这里就对应A、B、C,当其中有一个请求完之后就会再从urls里面再取出一个进行请求,这样依次类推,直到urls里面的20个请求都执行完才终止请求。

主要思路就是上面所述,但是在开发时我们要考虑一些特殊情况,如下:

  • urls的长度为0时,results就没有值,此时应该返回空数组
  • maxNum大于urls的长度时,应该取的是urls的长度,否则则是取maxNum
  • 需要定义一个count计数器来判断是否已全部请求完成
  • 因为没有考虑请求是否请求成功,所以请求成功或报错都应把结果保存在results集合中
  • results中的顺序需和urls中的保持一致

好,我的设计思路就是这样的,下面就要来开始开发工作啦~

开发

具体代码如下(代码中已备注有注释):

// 并发请求函数
const concurrencyRequest = (urls, maxNum) => {
    return new Promise((resolve) => {
        if (urls.length === 0) {
            resolve([]);
            return;
        }
        const results = [];
        let index = 0; // 下一个请求的下标
        let count = 0; // 当前请求完成的数量

        // 发送请求
        async function request() {
            if (index === urls.length) return;
            const i = index; // 保存序号,使result和urls相对应
            const url = urls[index];
            index++;
            console.log(url);
            try {
                const resp = await fetch(url);
                // resp 加入到results
                results[i] = resp;
            } catch (err) {
                // err 加入到results
                results[i] = err;
            } finally {
                count++;
                // 判断是否所有的请求都已完成
                if (count === urls.length) {
                    console.log('完成了');
                    resolve(results);
                }
                request();
            }
        }

        // maxNum和urls.length取最小进行调用
        const times = Math.min(maxNum, urls.length);
        for(let i = 0; i < times; i++) {
            request();
        }
    })
}

测试

测试代码如下:

const urls = [];
for (let i = 1; i <= 20; i++) {
    urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
}
concurrencyRequest(urls, 3).then(res => {
    console.log(res);
})

结果

下面通过运行代码来看看效果:

首先来看看控制台输出的结果,如下:

可以看到20个请求都请求完成,results里面也是按顺序打印出了结果。

然后再看看请求时请求数量是否每次都是3个,如下:

通过上面这个gif图可以很直观的看到,每次请求的数量都是3个,证明写的代码没有毛病,搞定!

至此,这个在实际开发中会遇见的前端控制并发请求的需求就实现完成了。代码相对来说没有太大的难度,只要把一些特殊情况给考虑完全,最后的实现也就没什么太大问题。最后,希望看完这篇文章之后你也能轻松掌握前端控制并发数量的问题,栓Q~

以上就是JavaScript实现控制并发请求数量的方法详解的详细内容,更多关于JavaScript控制并发请求数量的资料请关注脚本之家其它相关文章!

相关文章

  • Javascript 命名空间模式

    Javascript 命名空间模式

    命名空间是通过为项目或库创建一个全局对象,然后将所有功能添加到该全局变量中。通过减少程序中全局变量的数量,实现单全局变量,从而在具有大量函数、对象和其他变量的情况下不会造成全局污染,同时也避免了命名冲突等问题
    2013-11-11
  • 微信小程序scroll-view实现左右联动效果

    微信小程序scroll-view实现左右联动效果

    这篇文章主要为大家详细介绍了微信小程序scroll-view实现左右联动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 使用JavaScript实现检测网页是否为空闲状态

    使用JavaScript实现检测网页是否为空闲状态

    最近开发项目时,常碰到“用户在一定时间内无任何操作时,跳转到某个页面”的需求,所以本文就来使用JavaScript实现这一要求,需要的可以参考下
    2024-03-03
  • 原生JS实现简单的轮播图效果

    原生JS实现简单的轮播图效果

    这篇文章主要为大家详细介绍了原生JS实现简单的轮播图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • JS简单测试循环运行时间的方法

    JS简单测试循环运行时间的方法

    这篇文章主要介绍了JS简单测试循环运行时间的方法,涉及针对javascript中for循环、for...in循环及foreach循环的相关使用方法及运行时间测试,需要的朋友可以参考下
    2016-09-09
  • JS及PHP代码编写八大排序算法

    JS及PHP代码编写八大排序算法

    这篇文章主要为大家详细介绍了JS及PHP代码编写八大排序算法的相关资料,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • JS实现拖动模态框案例

    JS实现拖动模态框案例

    这篇文章主要为大家详细介绍了JS实现拖动模态框案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • 微信域名检测接口调用演示步骤(含PHP、Python)

    微信域名检测接口调用演示步骤(含PHP、Python)

    这篇文章主要介绍了微信域名检测接口调用演示步骤(含PHP、Python),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 概述BootStrap中role=

    概述BootStrap中role="form"及role作用角色

    这篇文章主要介绍了BootStrap中role="form"及role作用角色介绍,以及bootstrap栅栏系统css中的col-xs-*,col-sm-*,col-md-* 的意义简单介绍,需要的朋友参考下
    2016-12-12
  • JavaScript操纵窗口的方法小结

    JavaScript操纵窗口的方法小结

    一旦你得到了表示窗口的变量,你就能通过各种方法来操纵它。下面介绍一下对窗口的各种操作
    2013-06-06

最新评论