[实现一个批量请求函数
要求:
- 批量请求函数,最大并发数 maxNum
- 每当有一个请求返回,就留下一个空位,可以增加新的请求
- 所有请求完成后,结果按照 urls 里面的顺序依次发出。
const requestQueue = (maxNum = 6) => {
const queue = []
let current = 0
let resolvedCount = 0
let dequeueing = false
const dequeue = () => {
if (dequeueing) return
dequeueing = true
while (current < maxNum && queue.length > 0) {
current++
const currentPromise = queue.shift()
currentPromise()
.then(() => {
console.log('请求执行成功')
})
.catch((error) => {
console.error('请求执行失败:', error)
})
.finally(() => {
current--
resolvedCount++
if (queue.length === 0 && current === 0) {
resolveQueue()
} else if (queue.length > 0) {
dequeue()
}
dequeueing = false
})
}
}
const enqueue = (promiseFunc) => {
queue.push(promiseFunc)
if (queue.length === maxNum && !dequeueing) {
dequeue()
}
}
let resolveQueueCallback
let rejectQueueCallback
const queueEmptyPromise = new Promise((resolve, reject) => {
resolveQueueCallback = resolve
rejectQueueCallback = reject
})
const resolveQueue = () => {
if (typeof resolveQueueCallback === 'function') {
resolveQueueCallback(`所有请求已完成,共处理了 ${resolvedCount} 个请求。`)
resolveQueueCallback = null // 清除回调,防止重复调用
}
}
const rejectQueue = (error) => {
if (typeof rejectQueueCallback === 'function') {
rejectQueueCallback(error)
rejectQueueCallback = null // 清除回调,防止重复调用
}
}
return {
enqueue,
queueEmptyPromise,
rejectQueue, // 提供外部拒绝队列的接口
}
}
export default requestQueue
这样可以满足当请求池为空时,通知外部。
为什么需要一个请求池
因为Chrome的网络线程同时最多只能执行6 个,当你批量请求的时候,会导致后续一些优先级高的请求被阻塞。](<const requestQueue = (maxNum = 6) =%3E {
const queue = []
let current = 0
let resolvedCount = 0
const dequeue = () ⇒ {
while (current %3C maxNum && queue.length > 0) {
current++
const currentPromise = queue.shift()
currentPromise()
.then(() ⇒ {
console.log(‘请求执行成功’)
resolvedCount++
current—
checkQueue()
})
.catch((error) ⇒ {
console.error(‘请求执行失败:’, error)
// rejectQueue(error)
current—
checkQueue()
})
}
}
const enqueue = (promiseFunc) ⇒ {
queue.push(promiseFunc)
if (queue.length ⇐ maxNum) {
dequeue()
}
}
const checkQueue = () ⇒ {
if (queue.length = 0 && current = 0) {
resolveQueue()
} else if (queue.length > 0 && current < maxNum) {
dequeue()
}
}
let resolveQueueCallback
let rejectQueueCallback
const queueEmptyPromise = new Promise((resolve, reject) ⇒ {
resolveQueueCallback = resolve
rejectQueueCallback = reject
})
const resolveQueue = () ⇒ {
if (typeof resolveQueueCallback === ‘function’) {
resolveQueueCallback(resolvedCount)
resolveQueueCallback = null // 清除回调,防止重复调用
}
}
const rejectQueue = (error) ⇒ {
if (typeof rejectQueueCallback === ‘function’) {
rejectQueueCallback(error)
rejectQueueCallback = null // 清除回调,防止重复调用
}
}
return {
enqueue,
queueEmptyPromise,
rejectQueue, // 提供外部拒绝队列的接口
}
}
export default requestQueue>)