MST
星途 面试题库

面试题:JavaScript中复杂Promise链式调用与错误处理优化

假设有一系列异步任务,任务1返回Promise A,任务2依赖任务1的结果并返回Promise B,任务3依赖任务2的结果并返回Promise C。任务1、2、3都有可能抛出错误。请使用Promise链式调用实现这个流程,并且要求在某个任务出错时,后续未执行的任务不再执行,同时要以优雅的方式捕获并处理错误,将错误信息整理成特定格式(包含错误任务名称和错误信息)返回。请描述你代码中的错误处理策略以及为什么这样设计。
16.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
function task1() {
    return new Promise((resolve, reject) => {
        // 模拟异步操作
        setTimeout(() => {
            // 这里可以随机抛出错误模拟任务失败
            // Math.random() > 0.5? resolve('Task1 result') : reject(new Error('Task1 error'));
            resolve('Task1 result');
        }, 1000);
    });
}

function task2(result1) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 这里可以随机抛出错误模拟任务失败
            // Math.random() > 0.5? resolve(`Task2 result based on ${result1}`) : reject(new Error('Task2 error'));
            resolve(`Task2 result based on ${result1}`);
        }, 1000);
    });
}

function task3(result2) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 这里可以随机抛出错误模拟任务失败
            // Math.random() > 0.5? resolve(`Task3 result based on ${result2}`) : reject(new Error('Task3 error'));
            resolve(`Task3 result based on ${result2}`);
        }, 1000);
    });
}

function executeTasks() {
    return task1()
      .then(task1Result => task2(task1Result))
      .then(task2Result => task3(task2Result))
      .then(finalResult => {
            return finalResult;
        })
      .catch(error => {
            const errorInfo = {
                errorTaskName: '',
                errorMessage: ''
            };
            if (error.message.includes('Task1 error')) {
                errorInfo.errorTaskName = 'Task1';
                errorInfo.errorMessage = error.message;
            } else if (error.message.includes('Task2 error')) {
                errorInfo.errorTaskName = 'Task2';
                errorInfo.errorMessage = error.message;
            } else if (error.message.includes('Task3 error')) {
                errorInfo.errorTaskName = 'Task3';
                errorInfo.errorMessage = error.message;
            }
            return errorInfo;
        });
}

executeTasks().then(result => {
    console.log(result);
});

错误处理策略

  1. 链式调用中的.catch:在Promise链式调用的最后添加.catch方法来捕获整个链中任何一个Promise被拒绝时抛出的错误。这是因为Promise链式调用一旦某个Promise被拒绝,后续的.then回调将不会被执行,错误会沿着链条一直传递到最近的.catch块。
  2. 错误信息整理:在.catch块中,根据错误信息中的特定标识(如Task1 errorTask2 errorTask3 error)来判断是哪个任务抛出的错误,并将错误任务名称和错误信息整理成特定格式返回。这样设计可以清晰地知道是哪个任务出现了问题,方便调试和后续处理。
  3. 停止后续任务执行:由于Promise的特性,一旦某个Promise被拒绝,后续依赖于它的Promise不会被执行,这符合题目中在某个任务出错时,后续未执行的任务不再执行的要求。这种机制保证了在出现错误时,程序不会继续执行不必要的异步操作,节省资源并提高程序的稳定性。