关键点:1. 通过执行函数控制并发数量;2. 在单个请求结束后再次调用执行函数;3. 考察对promise的理解
// 模拟发送请求接收到数据:返回一个promise,time时间到了,promise完成
function timeout(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, time)
})
}
class SuperTask {
constructor(maxCount = 2) {
// 最大并发数量
this.maxCount = maxCount
// 请求队列
this.requestQueue = []
// 当前正在进行请求的并发数
this.currentCount = 0
}
// 添加任务到请求队列中
add(task) {
return new Promise((resolve, reject) => {
this.requestQueue.push({
task,
resolve,
reject
})
// 尝试执行任务
this.run()
})
}
// 执行任务:判断当前的并发数,执行我们的任务
run() {
while (this.currentCount < this.maxCount && this.requestQueue.length !== 0) {
// 拿出任务
const { task, resolve, reject } = this.requestQueue.shift()
this.currentCount++
// 执行任务,在执行完毕后,需要再次调用run
task().then(resolve, reject).finally(() => {
// 任务执行完毕
this.currentCount--
this.run()
})
}
}
}
const superTask = new SuperTask(2)
function addTask(time, name) {
superTask
.add(() => timeout(time))
.then(() => {
console.log(`任务${name}完成`)
})
}
addTask(10000, 1) // 10000s后输出:任务1完成
addTask(5000, 2) // 5000s后输出:任务2完成
addTask(3000, 3) // 8000s后输出:任务3完成
addTask(4000, 4) // 12000s后输出:任务4完成
addTask(5000, 5) // 15000s后输出:任务5完成
addTask(6000, 6) // 18000s后输出:任务6完成
/**
* 并发请求
* @param {string[]} urls 待请求的url数组
* @param {number} maxNum 最大并发数
*/
function concurRequest(urls, maxNum) {
return new Promise(resolve => {
// 边缘条件
if (urls.length === 0) {
resolve([])
return
}
// 存储结果
const result = new Array(urls.length).fill(null)
// 当前需要的请求位置
let index = 0
// 请求
async function request() {
const i = index
const url = urls[index]
index++
try {
const res = await fetch(url)
result[i] = res
} catch (err) {
result[i] = err
} finally {
// 递归调用下一次请求
// 判断当前请求队列是否遍历完
if (index === urls.length) {
// 收集结果
resolve(result)
return
}
request()
}
}
const min = Math.min(maxNum, urls.length)
for (let i = 0; i < min; i++) {
request()
}
})
}
const urls = []
for (let i = 1; i <= 100; i++) {
urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`)
}
concurRequest(urls, 100).then((res) => {
console.log(res);
})
面试题:浏览器的最大并发请求数量是多少?为什么这么设计?
在HTTP版本为1.1时,现代浏览器例如Chrome一般对同一域名的最大并发请求数量限制在6个,也就是对同一域开启的TCP链接最多为6个。这种设计主要是为了避免对服务器造成过大的负载,确保网络资源合理使用,并提高用户的网页加载速度和整体浏览体验。
如果并发请求数量过多,可能会导致服务器响应变慢,甚至无法响应,从而影响用户体验。