如何控制promise并发数
思路:
- 先发送3个,3个中哪个先响应了,立即发送第4个,第4个和前面没响应的两个中哪个先响应了,立即发送第5个,直到10个发送完
- 利用Promise.race()获取最先响应的请求
- 利用array.reduce实现队列执行
function sleep(time) {
return new Promise(resolve => {
setTimeout(resolve, time)
})
}
function loadData(url) {
return new Promise(async (resolve, reject) => {
await sleep(url.time)
resolve(url.info)
})
}
const urls =[
{info:'1', time:2000},
{info:'2', time:2000},
{info:'3', time:2000},
{info:'4', time:2000},
{info:'5', time:3000},
{info:'6', time:1000},
{info:'7', time:2000},
{info:'8', time:2000},
{info:'9', time:3000},
{info:'10', time:1000}
]
// 先发送3个,3个中哪个先响应了,立即发送第4个,
// 第4个和前面没响应的两个中哪个先响应了,立即发送第5个,直到10个发送完
function limitLoad(urls, handler, limit) {
// 将数组拷贝一份
let queue = [].concat(urls)
let promises = []
// 首先并发3个
promises = queue.splice(0, limit).map((url,index) => {
return handler(url).then(res => {
console.log(index, url);
// 用Promise.race找到先影响的脚标,下个请求插入到这个脚标位置来请求
return index
})
})
// 剩下的数组以队列的形式来执行
queue.reduce((p, url) => {
return p.then(index => {
promises[index] = handler(url).then(() => {
console.log(index, url);
return index // 继续返回脚标
})
return Promise.race(promises)
})
}, Promise.race(promises))
}
limitLoad(urls, loadData, 3)