所谓并发请求,就是指在一个时间点多个请求同时执行。当并发的请求超过一定数量时,会造成网络堵塞,服务器压力大崩溃或者其他高并发问题,此时需要限制并发请求的数量。
假如等待请求接口1000个,限制每次只能发出100个。即同一时刻最多有100个正在发送的请求。每当100个之中有一个请求完成时,则从待请求的接口(即剩余的900个待请求接口)中再取出一个发出。保证当前并发度仍旧为100。直至全部接口请求完成。
const apiList = [
'url___A',
'url___B',
'url___C',
'url___D',
'url___E',
'url___F',
'url___G',
]
let currentRequestList = []
const request = api => {
console.log(`${api} 请求start`)
const wait = Math.random() * 3000
console.log(`${api} 请求时间 ${wait}`)
currentRequestList.push(api)
if (currentRequestList.length === 2) {
console.log('当前正在请求的接口 -> ', currentRequestList.toString())
}
return new Promise(resolve => {
setTimeout(() => {
console.log(`${api} 请求end`)
const index = currentRequestList.findIndex(c => c === api)
currentRequestList.splice(index, 1)
resolve(`获取接口“${api}”的数据`)
}, wait)
})
}
const requestWithLimit = (apiList, limit = 3, callback) => {
let count = 0
const run = () => {
count++
const api = apiList.shift()
request(api).then(res => {
count--
console.log(res)
if (apiList.length && count < limit) {
run()
}
if (!apiList.length && !count) {
callback('全部执行完毕!')
}
})
}
for (let i = 0; i < limit; i++) {
run()
}
}
requestWithLimit(apiList, 2, res => {
console.log('回调函数', res)
})
用人说用 for 循环来并发太 low 了,能否采用 Promise.all 的写法呢? 这个想法很不错,答案是可以的。Promise.all 接收一个元素为 Promise 对象的数组作为参数,这里控制并发的本质就是控制该数组的长度。
Promise.all([p1, p2, p3...])
const requestWithLimit = (apiList, limit = 3) => {
let list = [...apiList]
let map = new Map()
const run = () => {
if (list.length) {
const api = list.shift()
return request(api).then(res => {
map.set(api, res)
return run()
})
}
}
const promiseList = Array(Math.min(apiList.length, limit)).fill(Promise.resolve()).map(promise => promise.then(run))
return Promise.all(promiseList).then(() => {
return apiList.map(c => map.get(c))
})
}
requestWithLimit(apiList, 2).then(res => {
console.log('请求完毕:', res)
})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)