MST

星途 面试题库

面试题:JavaScript生成器在复杂异步场景中的应用

假设有一个场景,需要依次发起多个异步请求,且每个请求的参数依赖于上一个请求的返回结果。同时,其中部分请求可能会失败并需要进行重试机制。请使用JavaScript生成器和相关异步处理方法来实现这个功能,并解释实现思路。
13.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

实现代码

function asyncRequestWithRetry(url, retries = 3, delay = 1000) {
    return new Promise((resolve, reject) => {
        let attempt = 0;
        const makeRequest = () => {
            // 模拟异步请求
            setTimeout(() => {
                const shouldFail = Math.random() < 0.5; // 模拟50%失败率
                if (shouldFail && attempt < retries) {
                    attempt++;
                    setTimeout(makeRequest, delay);
                } else if (shouldFail && attempt >= retries) {
                    reject(new Error(`Request to ${url} failed after ${retries} attempts`));
                } else {
                    resolve({ data: `Response from ${url}` });
                }
            }, 1000);
        };
        makeRequest();
    });
}

function* requestGenerator() {
    const initialUrl = 'https://example.com/initial';
    try {
        let response = yield asyncRequestWithRetry(initialUrl);
        yield* iterateRequests(response.data, 5);
    } catch (error) {
        console.error('Initial request failed:', error);
    }
}

function* iterateRequests(data, count) {
    for (let i = 1; i <= count; i++) {
        const url = `https://example.com/${i}?param=${data}`;
        try {
            let response = yield asyncRequestWithRetry(url);
            console.log(`Request ${i} success:`, response);
        } catch (error) {
            console.error(`Request ${i} failed:`, error);
        }
    }
}

function runGenerator(generator) {
    const iterator = generator();
    function handleResult(result) {
        if (result.done) {
            return;
        }
        result.value.then((response) => {
            handleResult(iterator.next(response));
        }).catch((error) => {
            console.error('Error in request:', error);
            handleResult(iterator.throw(error));
        });
    }
    handleResult(iterator.next());
}

runGenerator(requestGenerator);

实现思路

  1. 异步请求带重试机制asyncRequestWithRetry函数创建一个Promise来模拟异步请求。它接受URL、最大重试次数retries和重试延迟时间delay作为参数。在每次请求失败且重试次数未达到上限时,它会延迟一段时间后重新发起请求。当达到最大重试次数仍失败时,Promise被拒绝。
  2. 生成器函数
    • requestGenerator是主生成器函数,它发起第一个请求并处理可能的错误。然后,它通过yield*委托给iterateRequests生成器函数。
    • iterateRequests生成器函数负责依次发起后续请求,每个请求的URL依赖于上一个请求的返回数据。在每次请求成功或失败时,都会进行相应的日志记录。
  3. 运行生成器runGenerator函数用于运行生成器。它通过迭代生成器并处理每个yield返回的Promise来实现依次执行异步请求。如果Promise被拒绝,错误会被捕获并通过iterator.throw(error)传递给生成器内部进行处理。