当有一种需求需要循环调用接口时,由于并发产生的问题,正常的foreach循环由于是同步进行只能成功一次后续都失败
例
const postArr = [
{
id: 1,
age:12,
name: 'xiaohong'
},
{
id: 2,
age:12,
name: 'xiaohong1'
},
{
id: 3,
age:12,
name: 'xiaohong2'
},
]
const newData = []
const postApi = () => {
//请求接口
postArr.forEach(item => {
apiAdd(item).then(res=> {
newData.push(res.data)
})
})
}
只可以成功一次
正确使用-直接复制即可
/**task.js
* @param {每次同时执行的任务数量} parallelCount
*/
class SuperTask {
constructor(parallelCount = 1) {
this.parallelCount = parallelCount
this.tasks = []
this.runingCount = 0
}
add(task) {
return new Promise((resolve, reject) => {
this.tasks.push({
task,
resolve,
reject
})
this._run()
})
}
_run() {
while (this.runingCount < this.parallelCount && this.tasks.length) {
const { task, resolve, reject } = this.tasks.shift()
this.runingCount++
Promise.resolve(task())
.then(resolve, reject)
.finally(() => {
this.runingCount--
this._run()
})
}
}
}
export const superTask = new SuperTask()
使用
<template>
<div>
<el-button @click="generateYD">开始请求</el-botton>
</div>
</template>
<script setup>
import { superTask } from '../task.js'
const postArr = [
{
id: 1,
age:12,
name: 'xiaohong'
},
{
id: 2,
age:12,
name: 'xiaohong1'
},
{
id: 3,
age:12,
name: 'xiaohong2'
},
]
const newData = []
const generateYD = () => {
postArr.forEach(item=> {
addTask(item)
})
}
const breakReserve = (item) => {
return new Promise((resolve, reject)=> {
//上传接口
postReserve(item).then(res=> {
resolve(res) //抛出结果
})
})
}
const addTack = (item)=> {
//每次请求成功得到结果之后继续请求下一个,直到结束
superTask.add(()=>breakReserve(item)).then(res=>{
//console.log(res) 每请求一次放回一次结果
newData.push(res.data)
})
}
</script>