前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一道关于并发控制的面试题

一道关于并发控制的面试题

作者头像
挥刀北上
发布2019-07-19 15:16:53
6810
发布2019-07-19 15:16:53
举报
文章被收录于专栏:Node.js开发

很久以前发了一篇文章,文章里主要探讨了这样一个问题,页面中需要发送多次ajax请求,如何确保所有数据返回后才对数据一起进行操作,文章名称为:

Promise的all和race方法的使用,简而言之3种方法,Promise的all方法,计数器,回调嵌套。想想那已经是17年的文章了,时间过得真是飞快。

就在前不久这个并发的问题升级了,问题变成了这样子的,比如某个页面需要请求资源,需要发送100次请求,100次不能同时同时发送,要做到并发控制,,要求你的页面或程序最大并发数只能是5,请求数大于5时只能等待,请求数小于5时从100中拿出一条来发送。

这段代码或者这段程序如何完成呢?

我们用一张图来表示一下这个场景,100个人去食堂打饭,只有5个窗口,如何才能做到效率最高呢?

第一种情况人员分成五组,分别排队,每队二十人。如图:

这张图初看好像没有问题,但是仔细思考下,假如1、2、3、4窗口的人很快就完成了,5的队伍中有个2B有选择恐惧症加拖延症,就会出现如下所示的情况:

1,2,3,4空闲了。所以不能这样做,抛弃这种设置,代码肯定不能按照这种形式来实现。

第二种设计如图:

仔细看看这种设计,乍一看好像队伍变长了,但是处理的效率大大提高了,并且窗口也没有空闲,这样就算碰见2B也不用担心了,因为这个2B不能阻止所有窗口。

那基于这样的设计,代码该如何实现呢?

这里我们用定时器setTimeout来模拟异步请求,模拟代码如下:

代码语言:javascript
复制
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30];
var l = arr.length

// 限制的请求数量
var limit = 0;
// 计数器
var count = 0;
// 完成的请求数量
var sum = 0;
// 请求结果返回这个数组的每一项。
var result=[];

// 定义一个递归函数,函数执行时,根据计数器先判断当前正在请求的数量;
// 请求数量小于5并且请求url数组的长度大于0,那么就发送请求,否则啥也不干
// 满足条件的话,计数器count自增1,并且从arr中pop出一条url,然后进行异步操作
// 这里用定时器模拟异步操作,异步操作完成后,计数器自减1并处理结果,sum总的计数器加1
// 递归调用自己

var asyncreq = function(){
    if(count<5&&arr.length>0){
        count++;
        console.log("现在并发数是",count);
        let ele = arr.pop();
        setTimeout(()=>{
            count--;
            console.log("现在并发数是",count);
            asyncreq()
            sum++
            result.push(ele*10);
            if(sum==l){
                console.log(result.length);
            }
        },5000*Math.random()+3000)
    }
}
// 瞬间开启5个请求
for (let i = 0; i < 5; i++) {
    asyncreq();
}

执行结果:

时刻保持5的并发数直至结束。

回顾一下上面的代码,主要应用了递归函数,每个函数的内部首先判断当前请求数的数量,和请求url的剩余数量,当请求数小于5,请求url剩余量大于0,满足条件后,执行异步操作,pop出一条url,异步造作完成后,计数器自减,总的请求数量自增,如果总的请求数量与初始url数量一致,处理总的结果。

以上便是对大量异步请求控制并发数的一种操作方法,当然还有其他方法,欢迎大家在留言区探讨。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nodejs全栈开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Promise的all和race方法的使用,简而言之3种方法,Promise的all方法,计数器,回调嵌套。想想那已经是17年的文章了,时间过得真是飞快。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档