头条前端笔试题 - 实现一个带并发限制的promise异步调度器

这道题是之前从同事那里要过来的头条笔试题的其中一个,而且promise 并发执行问题在面试中很常见,所以今天就来简单的写下相关的代码,可能方法不止一个,算是抛砖引玉吧。

题目详情:

我们都知道promise.all方法可以执行多个promise,你给他多少个他就执行多少个,而且是一起执行,也就是并发执行。如果你给他100个,他会同时执行100个,如果这100个promise内都包含网络请求呢?

可能有人说,这种场景不多吧,一个页面内加起来就没几个接口,何况是并发请求了

但是如果让你做个文件分片上传呢?一个几百兆的文件分片后可能有几百个片段了吧。当然这也是一种极端情况,不过这确实是一个很明显的问题,还是需要解决的。

所以需要我们控制同时执行的promise个数,比如控制为2个,后面的所有promise都排队等待前面的执行完成。

进入正题,上面的代码不控制并发的情况下的执行顺序应该是

3
4
2
1

控制并发为2后的执行结果是

2
3
1
4

这个题本身也并不难,主要还是考察对题目的理解。

简单说下思路

  1. 先把要执行的promise function 存到数组内

  2. 既然是最多为2个,那我们必然是要启动的时候就要让两个promise函数执行

  3. 设置一个临时变量,表示当前执行ing几个promise

  4. 然后一个promise执行完成将临时变量-1

  5. 然后借助递归重复执行

代码如下:

function Scheduler(){
    this.list=[]
    this.add=function(promiseCreator){
       this.list.push(promiseCreator)
    }
    
    this.maxCount=2;

    
    var tempRunIndex=0;

    this.taskStart=function(){
       for(var i =0 ;i<this.maxCount;i++){
           request.bind(this)()
       }
    }

    function request(){
      
        if(!this.list || !this.list.length || tempRunIndex>=this.maxCount){
            return
        }
       
        tempRunIndex++
        this.list.shift()().then(()=>{
            tempRunIndex--
            request.bind(this)()
        })
    }
}

function timeout(time){
    return new Promise(resolve=>{
        setTimeout(resolve,time)
    })
}

var scheduler = new Scheduler()

function addTask(time,order){
    scheduler.add(()=>timeout(time).then(()=>console.log(order)))
}


addTask(1000,1)
addTask(500,2)
addTask(300,3)
addTask(400,4)

scheduler.taskStart()

ok,上面是全部代码,下面是执行结果

有什么问题或者更好的建议欢迎留言交流O(∩_∩)O~~

点赞是最大的支持 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 8

打赏作者

zz_jesse

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值