class Scheduler {
constructor(max = 2) {
// 最大运行数量
this.maxNum = max
// 当前运行数量
this.runNum = 0
// 事件队列
this.runlist = []
this.resolve = null
// 运行完成的数量
this.complateNum = 0
}
getRes(list, max) {
this.list = list
this.maxNum = max
this.result = []
return new Promise((resolve, reject) => {
this.resolve = resolve
// 如果事件队列中的事件数量为0,直接返回结果
if (this.list.length === 0) {
this.resolve(this.result)
return
}
this.runList()
})
}
runList() {
// 因为最后的结果需要按照顺序返回,所有给每个事件增加一个下标,用来存值
for (let i = 0; i < this.list.length; i++) {
this.runlist.push({index: i, cb: this.list[i]})
}
this.run()
}
run() {
// 如果当前正在运行的数量小于最大运行数量,并且事件列表中有值
while (this.runNum < this.maxNum && this.runlist.length) {
// 从事件列表中取第一项的值然后运行
let itempro = this.runlist.shift()
let cb = itempro.cb
let index = itempro.index
this.runNum++
cb.then(res => {
this.result[index] = res
}).catch(err => {
this.result[index] = err
}).finally(() => {
this.complateNum++
this.runNum--
console.log(this.result)
// 当所有的事件执行完成以后返回值
if (this.complateNum == this.list.length) {
this.resolve(this.result)
} else {
this.run()
}
})
}
}
}
let proArr = []
for (let i = 0; i < 100; i++) {
let randomTime = Math.floor(Math.random() * 10) + 1
proArr.push(new Promise((resolve) => {
//模拟接口调用
setTimeout(() => {
resolve('-------'+i+'--------'+randomTime)
}, randomTime*1000)
}) )
}
let scheduler = new Scheduler()
scheduler.getRes(proArr, 2).then(res => {
console.log('res', res)
})
一次调用多个接口按顺序返回结果
最新推荐文章于 2024-05-30 13:59:14 发布