MST

星途 面试题库

面试题:JavaScript Promise 错误处理与异步流程控制的深度结合

在一个复杂的异步场景中,有多个相互依赖的 Promise 操作,其中一些操作可能会失败并需要进行特定的错误处理和重试机制。请设计一个方案,利用 Promise 实现这个异步流程,要求在错误处理时能够做到局部错误不影响整体流程继续执行,并对失败的操作进行最多3次重试。请给出完整的代码实现及详细的注释说明。
37.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
// 模拟一个异步操作函数,它可能成功也可能失败
function asyncOperation() {
    return new Promise((resolve, reject) => {
        // 这里简单模拟50%的失败率
        if (Math.random() < 0.5) {
            resolve('操作成功');
        } else {
            reject('操作失败');
        }
    });
}

// 重试函数,最多重试maxRetries次
function retryOperation(operation, maxRetries = 3) {
    let retries = 0;
    return new Promise((resolve, reject) => {
        function run() {
            operation()
               .then(resolve)
               .catch(err => {
                    if (retries < maxRetries) {
                        retries++;
                        console.log(`第 ${retries} 次重试`);
                        run();
                    } else {
                        reject(err);
                    }
                });
        }
        run();
    });
}

// 主异步流程函数
async function mainAsyncFlow() {
    const results = [];
    try {
        // 假设这里有多个相互依赖的Promise操作
        const result1 = await retryOperation(asyncOperation);
        results.push(result1);
        console.log('操作1完成');

        const result2 = await retryOperation(asyncOperation);
        results.push(result2);
        console.log('操作2完成');

        // 以此类推添加更多操作

    } catch (err) {
        // 这里处理整体流程中的错误,虽然局部错误不影响整体流程继续执行,但如果所有重试都失败,这里会捕获到最终错误
        console.error('整体流程出现错误:', err);
    }
    return results;
}

// 执行主异步流程
mainAsyncFlow()
   .then(results => {
        console.log('所有操作完成,结果:', results);
    })
   .catch(err => {
        console.error('主流程最终错误:', err);
    });

代码说明:

  1. asyncOperation函数
    • 模拟一个异步操作,使用Promise来包装。
    • 通过Math.random()函数模拟50%的失败率,成功时调用resolve,失败时调用reject
  2. retryOperation函数
    • 接受一个异步操作函数operation和最大重试次数maxRetries(默认3次)。
    • 使用闭包保存重试次数retries
    • 每次执行operation,成功则直接resolve结果;失败时检查重试次数,如果未达到最大重试次数则进行重试,否则reject错误。
  3. mainAsyncFlow函数
    • 使用async/await语法来管理异步流程。
    • 调用retryOperation来执行每个相互依赖的异步操作,并将结果保存到results数组中。
    • 使用try/catch块捕获每个操作重试失败的错误,局部错误不会影响整体流程继续执行。
  4. 执行部分
    • 调用mainAsyncFlow启动整个异步流程,在then块中处理最终成功的结果,在catch块中处理主流程中的最终错误。