一、场景描述
假设我的数据依赖上一个数据才能执行,也就是某个操作(例如获取数据)可能依赖于另一个操作的结果。也就涉及到了处理异步操作,假设我们有两个 API 接口
fetchDataA()
:获取用户信息
fetchDataB(userId)
:根据用户 ID 获取该用户的订单列表
获取用户的订单需要依赖于先获取用户的信息。因此,我们需要确保在调用 fetchDataB
之前,先等待 fetchDataA
完成并获取所需的数据。
解决这个问题就涉及到异步编程,事件等待,我们采用promise进行解决:
二、使用promise实现异步
Promise: Promise 是一种用于表示异步操作最终完成或失败的对象。它可以处于三种状态之一:待定(pending)、已解决(fulfilled)、已拒绝(rejected)。
首先,我们创建两个模拟的 API 函数。这些函数返回 Promise,以模仿真实的网络请求。
function fetchDataA() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 模拟成功获取用户数据
const userData = { id: 1, name: "John Doe" };
resolve(userData);
}, 1000); // 模拟延迟
});
}
function fetchDataB(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 模拟成功获取用户订单数据
const ordersData = [
{ orderId: 101, product: "Laptop", userId },
{ orderId: 102, product: "Phone", userId }
];
resolve(ordersData);
}, 1000); // 模拟延迟
});
}
- 在
fetchDataA
和fetchDataB
中,我们使用setTimeout
模拟了一个异步操作,并在一定时间后通过resolve
返回结果。如果有错误发生,可以使用reject
将其传递出去。
或者假设获取数据的方法,你封装成这样:
getList() {
return new Promise((resolve, reject) => {
// 异步操作,例如获取律师列表
// 假设是一个 AJAX 请求
fetch('api/lawyerList')
.then(response => response.json())
.then(data => {
this.list= data; // 假设将数据存储到实例属性中
resolve(); // 数据成功获取,解决 Promise
})
.catch(error => {
reject(error); // 在发生错误时拒绝 Promise
});
});
}
获取到list之后,changenav需要这个list传给另外一个调用接口的函数:
this.getList()
.then(() => {
//依赖list数据再发送另外一个请求
this.changenav(this.list);
})
.catch(error => {
console.error("error", error);
// 处理错误,例如提示用户
});
因为getList方法是返回一个promise对象,所以在外部调用时,可以使用他身上的then,catch等微任务。
三、使用async/await实现异步
async
函数使得我们可以编写异步代码而像同步代码一样易于理解。await
关键字用于等待 Promise 的解决。
还是利用上面的fetchDataA()和fetchDataB()
async function loadUserDataAndOrders() {
try {
console.log("开始获取用户数据...");
// 等待 fetchDataA 的结果
const userData = await fetchDataA();
console.log("用户数据获取成功:", userData);
console.log("开始获取用户订单数据...");
// 使用从 fetchDataA 获取到的 userId 来获取订单数据
const ordersData = await fetchDataB(userData.id);
console.log("用户订单数据获取成功:", ordersData);
} catch (error) {
console.error("发生错误:", error);
}
}
// 调用主函数
loadUserDataAndOrders();
loadUserDataAndOrders
是一个async
函数,允许我们在其中使用await
。- 当我们调用
await fetchDataA()
时,代码执行会暂停,直到fetchDataA
完成并返回结果。一旦完成,结果将被分配给userData
,并且我们可以安全地使用这个数据进行后续操作。 - 同样地,
await fetchDataB(userData.id)
会在获取用户 ID 后再进行订单数据的请求。 - 我们使用
try/catch
块来捕获任何在异步操作中抛出的错误,这样可以保证无论是在获取用户数据还是订单数据时,如果出错,都能得到恰当的处理。
通过使用 Promise 和 async/await,我们能够以清晰和可维护的方式处理复杂的异步逻辑。这样不仅使代码更简洁,更容易理解,同时也提高了错误处理的能力。