简单场景:请根据axios帮我编写一个前端代码来处理异步接口回调地狱的问题,要求提供两个接口,先请求接口1结束后,再请求接口2
办法一:Axios顺序请求处理
import axios from 'axios';
// 接口1:获取用户基本信息
function fetchUserInfo(userId) {
return axios.get(`/api/user/${userId}`)
.then(response => {
console.log('接口1成功:', response.data);
return response.data; // 将结果传递给下一个then
})
.catch(error => {
console.error('接口1失败:', error);
throw error; // 抛出错误以便后续捕获
});
}
// 接口2:获取用户订单信息
function fetchUserOrders(userId) {
return axios.get(`/api/orders/${userId}`)
.then(response => {
console.log('接口2成功:', response.data);
return response.data;
})
.catch(error => {
console.error('接口2失败:', error);
throw error;
});
}
// 顺序调用两个接口
function fetchUserDataSequentially(userId) {
// 开始请求链
fetchUserInfo(userId)
.then(userInfo => {
// 接口1成功后调用接口2
return fetchUserOrders(userId)
.then(orders => {
// 合并两个接口的数据
return {
userInfo: userInfo,
orders: orders
};
});
})
.then(combinedData => {
console.log('最终数据:', combinedData);
// 这里可以处理合并后的数据
})
.catch(error => {
console.error('请求链中发生错误:', error);
});
}
// 测试调用
const testUserId = 123;
fetchUserDataSequentially(testUserId);
办法二:Axios async/await版本
import axios from 'axios';
async function fetchUserInfo(userId) {
try {
const response = await axios.get(`/api/user/${userId}`);
console.log('接口1成功:', response.data);
return response.data;
} catch (error) {
console.error('接口1失败:', error);
throw error;
}
}
async function fetchUserOrders(userId) {
try {
const response = await axios.get(`/api/orders/${userId}`);
console.log('接口2成功:', response.data);
return response.data;
} catch (error) {
console.error('接口2失败:', error);
throw error;
}
}
// 使用 async/await 的顺序调用
async function fetchUserDataSequentially(userId) {
try {
const userInfo = await fetchUserInfo(userId);
const orders = await fetchUserOrders(userId);
const combinedData = {
userInfo: userInfo,
orders: orders
};
console.log('最终数据:', combinedData);
return combinedData;
} catch (error) {
console.error('请求链中发生错误:', error);
throw error;
}
}
// 测试调用
(async () => {
const testUserId = 123;
try {
await fetchUserDataSequentially(testUserId);
} catch (error) {
// 错误处理
}
})();
关键点说明:
-
Promise 链式调用 :通过
.then()方法确保接口1完成后再调用接口2 -
错误处理:每个函数都有独立的错误处理,同时整个调用链也有统一错误处理
-
数据传递:将接口1的结果传递给接口2的调用过程
-
async/await:更直观的同步写法实现异步操作,推荐使用此版本
测试说明:
-
代码中已包含测试调用部分,使用
testUserId = 123作为示例 -
实际使用时需要替换为真实的 API 端点地址和用户 ID
办法三:Axios Promise链式调用版本
import axios from 'axios';
function fetchUserInfo(userId) {
return axios.get(`/api/user/${userId}`)
.then(response => {
console.log('接口1成功:', response.data);
return response.data;
})
.catch(error => {
console.error('接口1失败:', error);
throw error; // 继续抛出错误以便外部捕获
});
}
function fetchUserOrders(userId) {
return axios.get(`/api/orders/${userId}`)
.then(response => {
console.log('接口2成功:', response.data);
return response.data;
})
.catch(error => {
console.error('接口2失败:', error);
throw error;
});
}
// 使用 Promise 链式调用的顺序请求
function fetchUserDataSequentially(userId) {
let userInfo; // 用于存储第一个接口的结果
return fetchUserInfo(userId)
.then(info => {
userInfo = info;
return fetchUserOrders(userId);
})
.then(orders => {
const combinedData = {
userInfo: userInfo,
orders: orders
};
console.log('最终数据:', combinedData);
return combinedData;
})
.catch(error => {
console.error('请求链中发生错误:', error);
throw error;
});
}
// 测试调用
const testUserId = 123;
fetchUserDataSequentially(testUserId)
.then(data => {
console.log('完整数据获取成功:', data);
})
.catch(error => {
console.error('完整请求失败:', error);
});
Promise 链式调用结构:
- 使用
.then()方法链式调用替代async/await - 通过返回新的 Promise 实现链式调用
数据传递机制:
- 使用闭包变量
userInfo暂存第一个接口的结果 - 在最后一个
.then()中组合两个接口的数据
错误处理优化:
- 每个独立请求都有自己的错误处理
- 最外层有统一的错误捕获
办法四:Axios链式调用隐式返回版
import axios from 'axios';
function fetchUserDataSequentially(userId) {
return axios.get(`/api/user/${userId}`)
.then(userResponse => (
console.log('接口1成功:', userResponse.data),
axios.get(`/api/orders/${userId}`)
.then(ordersResponse => (
console.log('接口2成功:', ordersResponse.data),
{ userInfo: userResponse.data, orders: ordersResponse.data }
))
))
.catch(error => {
console.error('请求链中发生错误:', error);
throw error;
});
}
// 测试调用
const testUserId = 123;
fetchUserDataSequentially(testUserId)
.then(combinedData => console.log('完整数据获取成功:', combinedData))
.catch(error => console.error('完整请求失败:', error));
办法五:Vue Axios链式调用优化版
import axios from 'axios';
export default {
data() {
return {
userInfo: null,
orders: null
}
},
methods: {
fetchUserDataSequentially(userId) {
axios.get(`/api/user/${userId}`)
.then(userResponse => {
console.log('接口1成功:', userResponse.data);
this.userInfo = userResponse.data;
return axios.get(`/api/orders/${userId}`);
})
.then(ordersResponse => {
console.log('接口2成功:', ordersResponse.data);
this.orders = ordersResponse.data;
})
.catch(error => {
console.error('请求链中发生错误:', error);
throw error;
});
}
},
mounted() {
// 测试调用
this.fetchUserDataSequentially(123);
}
}
关键优化点说明:
Vue 数据绑定:
- 直接在
data()中定义userInfo和orders - 通过
this.userInfo和this.orders直接设置响应式数据
链式调用优化:
- 去除了最外层的
return语句 - 使用连续的
.then()链式调用 - 第一个
.then()设置userInfo - 第二个
.then()设置orders