实现promise并发控制
一般有两种考法:
第一种考法
实现一个类,类有个add函数接收一个promise,类另外有个whenAllDone函数返回一个promise,当所有接收的promise都执行完成时,返回promise状态为fulfilled,并返回promise数组的执行结果。
实现代码展示
js
class PromiseConcurrent {
constructor(max) {
this.max = max // 最大并发数
this.running = 0 // 当前正在运行的promise数量
this.queue = [] // 等待执行的promise队列
this.result = [] // 存储每个promise的执行结果
this.total = 0 // 记录promise的总数量
this.resolveAll = null // 所有promise执行完成后的resolve函数
}
next() {
if (this.queue.length === 0 || this.running >= this.max) {
return
}
this.running++
const {promise, index} = this.queue.shift()
promise.then((res) => {
this.result[index] = res
this.running--
this.next()
})
}
add(promise) {
this.queue.push({
promise,
index: this.total
})
this.result[index] = null
this.total++
if (this.running < this.max) {
this.next()
}
}
whenAllDone() {
return new Promise((resolve, reject) => {
this.resolveAll = resolve
if (this.queue.length === 0) {
this.resolveAll(this.result)
}
})
}
}使用示例:
js
const promiseConcurrent = new PromiseConcurrent(2)
promiseConcurrent.add(Promise.resolve(1))
promiseConcurrent.add(Promise.resolve(2))
promiseConcurrent.add(Promise.resolve(3))
promiseConcurrent.whenAllDone().then((res) => {
console.log(res) // [1, 2, 3]
})第二种考法
实现一个类,类有个add函数接收一个promise并返回一个新的promise,新的promise状态与接收的promise状态相同,且返回值为接收的promise的执行结果。
👆这种考的多
实现代码展示
js
class PromiseConcurrent {
constructor(max) {
this.max = max // 最大并发数
this.running = 0 // 当前正在运行的promise数量
this.queue = [] // 等待执行的promise队列
}
next() {
if (this.queue.length === 0 || this.running >= this.max) {
return
}
this.running++
const { promise, resolve } = this.queue.shift()
promise().then((res) => {
resolve(res)
this.running--
this.next()
})
}
add(promise) {
return new Promise((resolve) => {
this.queue.push({
promise,
resolve,
})
if (this.running < this.max) {
this.next()
}
})
}
}使用示例:
js
const promiseConcurrent = new PromiseConcurrent(2)
const task = (value, time) => {
return () => new Promise((resolve) => {
setTimeout(() => {
resolve(value)
}, time * 1000)
})
}
const task1 = promiseConcurrent.add(task(1, 4))
const task2 = promiseConcurrent.add(task(2, 1))
const task3 = promiseConcurrent.add(task(3, 2))
task1.then((res) => {
console.log(res)
})
task2.then((res) => {
console.log(res)
})
task3.then((res) => {
console.log(res)
})执行顺序为:task2 -> task3 -> task1
被考过的题:
第一道:
js
const promise1 = () => new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise1');
}, 1000);
});
const promise2 = () => new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise2');
}, 500);
});
const promise3 = () => new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise3');
}, 2000);
});
const promise4 = () => new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise4');
}, 1000);
});
// 正常执行顺序是 promise2 -> promise1 -> promise4 -> promise3
// 实现一个调度器,最多同时运行max个任务,其他任务等待
const Scheduler = (max) => {
// 实现代码
}
const scheduler = Scheduler(2);
scheduler(promise1).then((res) => {
console.log(res);
});
scheduler(promise2).then((res) => {
console.log(res);
});
scheduler(promise3).then((res) => {
console.log(res);
});
scheduler(promise4).then((res) => {
console.log(res);
});