MST

星途 面试题库

面试题:JavaScript 生成器与异步操作

在 JavaScript 中,如何利用生成器来处理异步操作,例如 AJAX 请求?请实现一个使用生成器函数来顺序发起两个 AJAX 请求(可以用 `setTimeout` 模拟 AJAX 延迟),并在每个请求成功后输出响应结果的示例代码。同时解释生成器在这种场景下相较于传统回调和 Promise 的优势和劣势。
10.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

示例代码

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);
    });
});

生成器相较于传统回调的优势

  1. 代码可读性更高:生成器函数的代码结构更接近同步代码,避免了回调地狱。例如在上述代码中,yield 使得异步操作看起来像是同步执行,更符合人类思维逻辑。
  2. 错误处理更方便:可以使用 try...catch 块来捕获生成器函数内部的错误,比在多层回调中处理错误更直观。

生成器相较于传统回调的劣势

  1. 需要手动执行:生成器函数不会自动执行,需要手动调用 next 方法来推进执行,这增加了使用的复杂性。不像回调函数,在异步操作完成后会自动调用。

生成器相较于 Promise 的优势

  1. 更细粒度的控制:生成器可以暂停和恢复执行,能够对异步操作的执行流程进行更细致的控制。例如,可以在 yield 处暂停,等待特定条件满足后再继续执行。
  2. 中间状态处理:可以在生成器执行过程中获取中间状态,而 Promise 一旦开始执行就无法中途干预。

生成器相较于 Promise 的劣势

  1. 语法相对复杂:生成器函数的语法比 Promise 更复杂,需要理解 yieldnext 等概念。
  2. 兼容性问题:在一些较老的 JavaScript 运行环境中,对生成器的支持不如 Promise 广泛。