示例代码
function ajaxCall(url, delay) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`Response from ${url}`);
}, delay);
});
}
function* asyncTasks() {
const response1 = yield ajaxCall('url1', 1000);
console.log(response1);
const response2 = yield ajaxCall('url2', 1000);
console.log(response2);
}
const task = asyncTasks();
task.next().value.then((result) => {
task.next(result).value.then((result) => {
task.next(result);
});
});
生成器相较于传统回调的优势
- 代码可读性更高:生成器函数的代码结构更接近同步代码,避免了回调地狱。例如在上述代码中,
yield
使得异步操作看起来像是同步执行,更符合人类思维逻辑。
- 错误处理更方便:可以使用
try...catch
块来捕获生成器函数内部的错误,比在多层回调中处理错误更直观。
生成器相较于传统回调的劣势
- 需要手动执行:生成器函数不会自动执行,需要手动调用
next
方法来推进执行,这增加了使用的复杂性。不像回调函数,在异步操作完成后会自动调用。
生成器相较于 Promise 的优势
- 更细粒度的控制:生成器可以暂停和恢复执行,能够对异步操作的执行流程进行更细致的控制。例如,可以在
yield
处暂停,等待特定条件满足后再继续执行。
- 中间状态处理:可以在生成器执行过程中获取中间状态,而 Promise 一旦开始执行就无法中途干预。
生成器相较于 Promise 的劣势
- 语法相对复杂:生成器函数的语法比 Promise 更复杂,需要理解
yield
、next
等概念。
- 兼容性问题:在一些较老的 JavaScript 运行环境中,对生成器的支持不如 Promise 广泛。