想要写这个的原因还要从上周五说起,我看面试题的过程发现有一个面试官问前端并发的问题,于是做了以下总结。
一、同一域名下
1.同一get请求,并发数量是1,超过数量后,只能等上一个请求完成后,下一个请求才会继续,否则超过的请求就会挂起来,在队列里排队。(这里你可以理解:一个女厕所只有一个坑位,有人在上厕所的时候,其他女生得排队等待)。
2.不同get/post,并发数量是6,超过6个以后也会在队列里排队。
二、原因
1.操作系统的端口数量有限,每条http请求会占用一个端口,操作系统一般会对总端口数量的一半开放给我们使用,为了防止我们消耗完资源。
2.性能:一个http对应一个线程,线程切换会造成性能损耗
3.并发数过多的话,会对服务器造成压力过大。
三、各浏览器并发数量统计
http:
Chrome、Firefox、IE10、11:6个
Safari、Opera:4个
IE9:10个
websocket:
IE: 6个
Safari:1273个
剩余:200+
四、解决方案
1.将请求资源分布到不同的域名下。(注意:这可能存在请求跨域的问题)
2.利用http缓存,对资源进行缓存处理。(浏览器缓存分为强缓存和协商缓存,按场景使用)
3.减少资源请求,按需加载,按需请求。
五、实现一个前端控制并发类代码
serviceControl.js
class serviceControl {
constructor(count) {
// 允许并发的最大数量
this.maxServiceCount = count;
this.apiMap = new Map();
}
addService(key,task) {
if (this.apiMap.size < this.maxServiceCount) {
this.apiMap.set(key, task)
}
}
reduceService(key) {
this.addService.delete(key);
}
runService(task) {
const key = new Date().getTime();
return new Promise((resolve, reject) => {
task()
.then(() =>{
this.addService(key, task)
resolve();
})
.catch(() => {
this.reduceService(key)
reject();
})
});
}
}
export default serviceControl;
index.js
import React from "react";
import serviceControl from './serviceControl';
function Congruent() {
const ServiceControl = new serviceControl(2);
const task = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(new Date().getTime());
resolve();
}, Math.random() * 1000);
})
}
ServiceControl.runService(task)
ServiceControl.runService(task)
ServiceControl.runService(task)
return <div>1</div>
}
export default Congruent;
我们控制请求并发类的实现方法有很多,大同小异,思路基本上都是类似的。好了不说了,我们换下一个话题。