一、说说Promise
Promise 是一种 JavaScript 技术,用于管理异步操作的流程,使得异步编程更加简单、易于理解和维护。Promise 对象有三种状态:pending、fulfilled 和 rejected。在异步操作执行成功时,Promise 对象进入 fulfilled 状态,可以通过 then 方法获取异步操作的结果。在异步操作执行失败时,Promise 对象进入 rejected 状态,可以通过 catch 方法获取异步操作的错误信息。
二、有没有用过Promise.all和Promise.race
Promise.all 方法用于并行执行多个异步操作,并在它们都成功完成后返回结果。Promise.all 方法接收一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象,它的解析值是一个包含所有异步操作结果的数组。如果其中任何一个异步操作失败,则 Promise.all 方法将立即抛出错误并返回 rejected 状态的 Promise 对象。
Promise.race 方法用于执行多个异步操作,但只返回第一个成功完成的异步操作的结果。Promise.race 方法接收一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象,它的解析值是第一个成功完成的异步操作的结果。如果其中任何一个异步操作失败,则 Promise.race 方法将立即抛出错误并返回 rejected 状态的 Promise 对象。
三、怎么用这两个方法实现异步并发执行控制器的
下面是一个使用 Promise.all 和 Promise.race 方法实现异步并发执行控制器的例子:
在这个例子中,我们定义了一个名为 AsyncController 的类,它可以控制异步操作的并发执行。maxConcurrency 参数指定了异步操作的最大并发数。我们通过 enqueue 方法将异步操作加入队列中,并在队列中等待执行。当队列中的异步操作未达到最大并发数时,tryDequeue 方法会尝试从队列中取出异步操作并执行。在执行异步操作时,我们使用 Promise 封装异步任务,并通过 Promise 的 resolve 和 reject 方法通知执行结果。runAll 方法使用 Promise.all 方法并行执行队列中的所有异步操作,并在它们都成功完成后返回结果。runRace 方法使用 Promise.race 方法并行执行队列中的所有异步操作,并在第一个成功完成的异步操作完成后返回结果。
class AsyncController {
constructor(maxConcurrency) {
this.maxConcurrency = maxConcurrency; // 最大并发数
this.runningCount = 0; // 正在运行的异步操作数
this.queue = []; // 等待执行的异步操作队列
}
enqueue(asyncTask) { // 将异步操作加入队列中
return new Promise((resolve, reject) => {
const task = () => { // 定义异步操作的执行任务
this.runningCount++; // 正在运行的异步操作数加 1
asyncTask() // 执行异步操作
.then(result => {
this.runningCount--; // 正在运行的异步操作数减 1
resolve(result); // 解析异步操作的结果
this.tryDequeue(); // 尝试执行队列中的下一个异步操作
})
.catch(error => {
this.runningCount--; // 正在运行的异步操作数减 1
reject(error); // 拒绝异步操作的结果
this.tryDequeue(); // 尝试执行队列中的下一个异步操作
});
};
this.queue.push(task); // 将异步操作的执行任务加入队列中
this.tryDequeue(); // 尝试执行队列中的异步操作
});
}
tryDequeue() { // 尝试执行队列中的异步操作
while (this.runningCount < this.maxConcurrency && this.queue.length > 0) {
const task = this.queue.shift(); // 取出队列中的第一个异步操作的执行任务
task(); // 执行异步操作的执行任务
}
}
runAll() { // 并行执行队列中的所有异步操作,并在它们都成功完成后返回结果
return Promise.all(this.queue.map(task => this.enqueue(task)));
}
runRace() { // 并行执行队列中的所有异步操作,并在第一个成功完成的异步操作完成后返回结果
return Promise.race(this.queue.map(task => this.enqueue(task)));
}
}