背景
接手了一个老项目,启动后首页打开请求三十几个接口,人都崩溃。只能想办法写promise优化下,现在基本上前端项目都是通过axios来实现异步请求的封装,异步编程。
明确概念
这里有几个概念需要明确一下
- 并发:并发是多个任务同时交替的执行(因为cpu执行指令的速度非常之快,它可以不必按顺序一段代码一段代码的执行,这样效率反而更加低下),这样看起来就是一起执行的,所以叫并发。
- 并行:可以理解为多个物理cpu或者有分布式系统,是真正的’同时’执行
- 并发控制:意思是多个并发的任务,一旦有任务完成,就立刻开启下一个任务
- 切片控制:将并发任务切片的分配出来,比如10个任务,切成2个片,每片有5个任务,当前一片的任务执行完毕,再开始下一个片的任务,这样明显效率没并发控制那么高了
思路
首先执行能执行的并发任务,根据并发的概念,每个任务执行完毕后,捞起下一个要执行的任务。
将关键步骤拆分出合适的函数来组织代码
- 循环去启动能执行的任务
- 取出任务并且推到执行器执行
- 执行器内更新当前的并发数,并且触发捞起任务
- 捞起任务里面可以触发最终的回调函数和调起执行器继续执行任务
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 31 32 33 34 35 36 37 38 39 40 41 42 43
|
sendRequest(
[() => request('1'),
() => request('2'),
() => request('3'),
() => request('4')],
3,
(res) => {
console.log(res)
})
function request(url, time = 1) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('请求结束:' + url);
if (Math.random() > 0.5) {
resolve('成功')
} else {
reject('错误;')
}
}, time * 1e3)
}) }
|
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| async function sendRequest(requestList,limits,callback){
const promises = []
const pool = new Set()
for(let request of requestList){
if(pool.size >= limits){
await Promise.race(pool)
.catch(err=>err)
}
const promise = request()
const cb = ()=>{
pool.delete(promise)
}
promise.then(cb,cb)
pool.add(promise)
promises.push(promise)
}
Promise.allSettled(promises).then(callback,callback)
}
|