前端控制异步并发
- 限制同时最大接口并发数量
代码
function fetch(url) {
// 模拟接口请求
return new Promise(resolve => {
setTimeout(() => {
resolve(url)
}, 1000 * Math.random())
})
}
function maxRequestLimit(arr, max, callback) {
let reqList = []
let i=0,count=0
const rear = arr.length-max
function getData() {
if (i === arr.length) return Promise.resolve() //这里return 阻止继续下去
let first = fetch(arr[i++])
reqList.push(first)
first.then(res => {
count++
reqList.splice(reqList.indexOf(first),1)
})
let p = Promise.resolve()
if(reqList.length>=max && count!==rear) p = Promise.race(reqList)
return p.then(()=>getData())
}
getData().then(()=> {
Promise.all(reqList).then(() => callback())
})
}
maxRequestLimit(['url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7', 'url8'], 3, () => { console.log('fetch end') })
解析
首先用Promise.all和race-api- 并发和取出最快的那一个请求
核心代码解析
- 每次请求经来都进行请求下一个fetch(arr[i++])
- 所有请求都进去了-不再进行请求 if (i === arr.length) return Promise.resolve()
- 拿到接口先让他异步执行-添加到reqList数组队列中
- 执行完毕后自己在队列中进行删除使用 indexOf拿到自己的索引
if (i === arr.length) return Promise.resolve()
let first = fetch(arr[i++])
reqList.pusnh(first)
first.then(res => {
count++
reqList.splice(reqList.indexOf(first), 1)
})
- 执行队列reqList如果大于等于并发值 就需要race取出最快的一个-否则就是Promise.resolve()延迟执行
- p.then(()=>getData()) 异步添加下一步的接口并发
let p = Promise.resolve()
if(reqList.length>=max && count!==rear) p = Promise.race(reqList)
return p.then(()=>getData())
- 执行getData异步then进行调用
- Promise.all控制执行队列的并发
- 队列执行完毕以后执行callback()
getData().then(() => {
Promise.all(reqList).then(() => callback())
})