MST

星途 面试题库

面试题:JavaScript 里 Promise 在复杂网络请求场景下的错误处理优化

在一个涉及多层嵌套网络请求(例如先获取用户基本信息,再根据用户信息中的 ID 获取详细资料,再根据详细资料中的某个字段获取相关推荐内容)的场景中,如何利用 Promise 进行链式调用并实现全面且优雅的错误处理,避免出现回调地狱?请描述思路并给出关键代码片段。
17.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

思路

  1. 使用 Promise 来封装每个网络请求,将异步操作转化为 Promise 对象。
  2. 通过 then 方法进行链式调用,使得代码逻辑更清晰,避免回调地狱。
  3. 在链式调用的最后添加 catch 方法,用于捕获整个链式调用过程中任何一个 Promise 被拒绝(rejected)时抛出的错误,实现全面的错误处理。

关键代码片段

假设我们有三个模拟的异步函数 fetchUserBasicInfofetchUserDetailsfetchRecommendations 分别对应三个网络请求。

// 模拟获取用户基本信息的异步函数
function fetchUserBasicInfo() {
    return new Promise((resolve, reject) => {
        // 模拟异步操作,例如通过 AJAX 请求
        setTimeout(() => {
            if (Math.random() > 0.5) {
                resolve({ id: 1 });
            } else {
                reject(new Error('获取用户基本信息失败'));
            }
        }, 1000);
    });
}

// 模拟根据用户ID获取详细资料的异步函数
function fetchUserDetails(userBasicInfo) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (Math.random() > 0.5) {
                resolve({...userBasicInfo, details: '详细资料', field: '某个字段' });
            } else {
                reject(new Error('获取用户详细资料失败'));
            }
        }, 1000);
    });
}

// 模拟根据详细资料中的某个字段获取相关推荐内容的异步函数
function fetchRecommendations(userDetails) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (Math.random() > 0.5) {
                resolve({...userDetails, recommendations: '推荐内容' });
            } else {
                reject(new Error('获取相关推荐内容失败'));
            }
        }, 1000);
    });
}

// 链式调用及错误处理
fetchUserBasicInfo()
   .then(fetchUserDetails)
   .then(fetchRecommendations)
   .then(result => {
        console.log('最终结果:', result);
    })
   .catch(error => {
        console.error('发生错误:', error.message);
    });

上述代码中,通过 Promise 的链式调用,将三个异步操作依次执行,并在最后统一处理可能出现的错误。如果任何一个 Promise 被拒绝,catch 块将会捕获并处理该错误。