做业务时,会遇到有多个请求要连续发送的情况,常见下面两种处理方式
1. 多个请求同时发送,请求池里有完成的下一个顶上
手写
// 同时发送5个请求,有完成的,下一个跟上
async function batchRequest(items, successFuc) {
const maxConcurrentRequests = 5
const requestsQueue = []
const paramsBase = {
userId: this.userId,
}
this.resObj.total = items.length
const calcMaskText = () => {
const successCount = this.resObj.successList.length
const failureCount = this.resObj.failList.length
const process = Math.floor(
((successCount + failureCount) / items.length) * 100
)
return `成功修改${successCount}条,失败${failureCount}条,共${items.length}条,执行进度:${process}%`
}
for (const item of items) {
const params = { ...paramsBase, customerIdList: [item] }
const request = remarkUpdate(params)
.then((res) => {
if (res.code === 0) {
if (res.data) {
this.resObj.successList.push(item)
this.$store.commit('openLoading', calcMaskText())
} else {
this.resObj.failList.push(item)
this.$store.commit('openLoading', calcMaskText())
}
} else {
this.resObj.failList.push(item)
this.$store.commit('openLoading', calcMaskText())
}
})
.catch(() => {
this.$store.commit('closeLoading')
return
})
// 添加到当前正在处理的 promises 列表
requestsQueue.push(request)
// 如果达到了最大并发数,等待其中一个完成
if (requestsQueue.length >= maxConcurrentRequests) {
await Promise.race(requestsQueue)
// 移除已完成的请求
const index = requestsQueue.findIndex(
(req) => req.isFulfilled || req.isRejected
)
if (index !== -1) requestsQueue.splice(index, 1)
}
}
// 等待所有剩余的 promises 完成
await Promise.all(requestsQueue)
this.$store.commit('closeLoading')
successFuc && successFuc()
}
可以用第三方库
- npm install p-limit
import pLimit from 'p-limit';
const limit = pLimit(5);// Returns a `limit` function.控制并发量
const input = [
limit(() => fetchSomething('foo')),
limit(() => fetchSomething('bar')),
limit(() => doSomething())
];
// Only one promise is run at once
const result = await Promise.all(input);
console.log(result);
2. 一堆请求,一个接一个地发
async function batchRequest(items, successFuc) {
const paramsBase = {
userId: this.userId,
}
this.resObj.total = items.length
const calcMaskText = () => {
const successCount = this.resObj.successList.length
const failureCount = this.resObj.failList.length
const process = Math.floor(
((successCount + failureCount) / items.length) * 100
)
return `成功修改${successCount}条,失败${failureCount}条,共${items.length}条,执行进度:${process}%`
}
for (const item of items) {
const params = { ...paramsBase, customerIdList: [item] }
try {
const res = await remarkUpdate(params)
if (res.code === 0) {
if (res.data) {
this.resObj.successList.push(item)
this.$store.commit('openLoading', calcMaskText())
} else {
this.resObj.failList.push(item)
this.$store.commit('openLoading', calcMaskText())
}
} else {
this.resObj.failList.push(item)
this.$store.commit('openLoading', calcMaskText())
}
} catch (error) {
this.resObj.failList.push(item)
this.$store.commit('openLoading', calcMaskText())
}
}
this.$store.commit('closeLoading')
successFuc && successFuc()
}