面试题答案
一键面试生成器相较于传统回调函数和 Promise 的优势
- 代码可读性更高:回调函数容易出现回调地狱,多层嵌套使得代码逻辑复杂且难以维护。Promise 通过链式调用解决了回调地狱问题,但生成器使用更接近同步代码的方式来编写异步代码,提升了可读性。
- 更细粒度的控制:生成器可以暂停和恢复执行,开发人员能够更精确地控制异步操作的流程,而 Promise 一旦开始就无法暂停。
- 错误处理更直观:在生成器中,错误处理可以像同步代码一样使用 try - catch 块,相比 Promise 的链式调用中通过
.catch()
捕获错误,更符合常规的编程习惯。
代码示例
function asyncTask1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 1 completed');
}, 1000);
});
}
function asyncTask2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 2 completed');
}, 1500);
});
}
function asyncTask3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Task 3 failed'));
}, 2000);
});
}
function* asyncTasks() {
try {
const result1 = yield asyncTask1();
console.log(result1);
const result2 = yield asyncTask2();
console.log(result2);
const result3 = yield asyncTask3();
console.log(result3);
} catch (error) {
console.error('Error:', error.message);
}
}
const taskIterator = asyncTasks();
function runTask() {
const task = taskIterator.next();
if (!task.done) {
task.value.then(data => {
taskIterator.next(data);
runTask();
}).catch(error => {
taskIterator.throw(error);
});
}
}
runTask();
在上述代码中:
asyncTask1
、asyncTask2
和asyncTask3
是模拟的异步任务,返回 Promise。asyncTasks
是一个生成器函数,使用yield
暂停执行并等待 Promise 解决。taskIterator
是生成器的迭代器。runTask
函数通过迭代器的next
方法来顺序执行异步任务,当 Promise 解决时,将结果传递给下一个yield
,如果 Promise 被拒绝,则通过throw
方法将错误传递给生成器内部的try - catch
块进行处理。