MST

星途 面试题库

面试题:JavaScript高级生成器返回值与异步操作深度融合

实现一个场景,使用生成器函数模拟异步操作队列。生成器函数内部有多个异步任务(可使用`setTimeout`模拟),每个任务执行完毕后返回一个结果,最后生成器函数返回所有结果的汇总信息。并且要在外部通过迭代器正确获取到生成器最终的返回值。详细阐述你的设计思路并编写代码。
27.4万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 生成器函数:定义一个生成器函数,在函数内部使用yield暂停执行,将每个异步任务(用setTimeout模拟)的结果通过yield返回。
  2. 异步任务执行:在生成器函数内,通过setTimeout模拟异步操作,当异步操作完成时,使用next方法将结果传递给生成器函数,并继续执行下一个yield
  3. 结果汇总:在生成器函数内部,收集每个异步任务的结果,最后返回汇总信息。
  4. 外部迭代器:在外部,使用迭代器来调用生成器函数,并正确获取生成器最终的返回值。

代码实现

function* asyncTaskQueue() {
    // 模拟第一个异步任务
    yield new Promise((resolve) => {
        setTimeout(() => {
            resolve('Task 1 result');
        }, 1000);
    });
    // 模拟第二个异步任务
    yield new Promise((resolve) => {
        setTimeout(() => {
            resolve('Task 2 result');
        }, 1500);
    });
    // 模拟第三个异步任务
    yield new Promise((resolve) => {
        setTimeout(() => {
            resolve('Task 3 result');
        }, 2000);
    });
    // 返回所有结果的汇总信息
    return {
        summary: 'All tasks completed',
        results: []
    };
}

// 创建生成器实例
const taskGenerator = asyncTaskQueue();

// 执行生成器并获取结果
async function runTasks() {
    let result = taskGenerator.next();
    const results = [];
    while (!result.done) {
        const value = await result.value;
        results.push(value);
        result = taskGenerator.next();
    }
    // 获取生成器最终的返回值
    const finalResult = result.value;
    finalResult.results = results;
    console.log(finalResult);
}

runTasks();

上述代码首先定义了一个生成器函数asyncTaskQueue,其中包含三个模拟的异步任务,每个任务使用setTimeout模拟并返回一个Promise。在外部,通过runTasks函数来迭代生成器,等待每个异步任务完成,收集结果,并最终获取生成器函数返回的汇总信息。