Promise面试题详解之控制并发
在写这篇文章的时候我有点犹豫,因为先前写过一篇类似的,一道关于并发控制的面试题,只不过那篇文章只给出了一种解决方案,后来在网上又陆续找到两种解决方案,说来惭愧,研究问题总是浅尝辄止,所以今天便放在一起,借着这道面试题再重新梳理一下。
题目是这样的:
有 8 个图片资源的 url,已经存储在数组 urls 中(即urls = [‘http://example.com/1.jpg', …., ‘http://example.com/8.jpg']),而且已经有一个函数 function loadImg,输入一个 url 链接,返回一个 Promise,该 Promise 在图片下载完成的时候 resolve,下载失败则 reject。
但是我们要求,任意时刻,同时下载的链接数量不可以超过 3 个。
请写一段代码实现这个需求,要求尽可能快速地将所有图片下载完成。
【Promise面试题详解之控制并发】已有代码如下:
文章图片
看到这个题目的时候,脑袋里瞬间想到了高效率排队买地铁票的情景,那个情景类似下图
文章图片
上图这样的排队和并发请求的场景基本类似,窗口只有三个,人超过三个之后,后面的人只能排队了。
首先想到的便是利用递归来做,就如这篇文章采取的措施一样,代码如下:
文章图片
以上是最常规的思路,我将加载图片的函数loadImg封装在bao函数内,根据条件判断,是否发送请求,请求完成后继续递归调用。
以上代码所有逻辑都写在了同一个函数中然后递归调用,可以优化一下,代码如下:
文章图片
上面代码将一个递归函数拆分成两个,一个函数只负责计数和发送请求,另外一个负责调度。
这里的请求既然已经被封装成了Promise,那么我们用Promise和saync、await来完成一下,代码如下:
文章图片
大致思路是,遍历执行urls.length长度的请求,但是当请求并发数大于限制时,超过的请求用await结合promise将其阻塞,并且将resolve填充到lock数组中,继续执行,并发过程中有图片加载完成后,从lock中推出一项resolve执行,lock相当于一个叫号机;以上代码可以优化为:
文章图片
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 杜月笙的口才
- Linux下面如何查看tomcat已经使用多少线程
- 皮夹克
- 解读《摩根集团》(1)
- 绘本与写作
- 蓝桥杯试题
- 麦田社群
- 面对苦难——如何化解
- 葱爷说股20190107