在 React 中,如果需要按顺序执行多个接口请求?
1.使用 async/await 串行化请求
import axios from "axios";
const fetchSequentialData = async () => {
try {
// 第一个请求
const response1 = await axios.get("https://api.example.com/endpoint1");
console.log("Response 1:", response1.data);
// 第二个请求依赖第一个请求的结果
const response2 = await axios.get(`https://api.example.com/endpoint2?id=${response1.data.id}`);
console.log("Response 2:", response2.data);
// 第三个请求依赖第二个请求的结果
const response3 = await axios.get(`https://api.example.com/endpoint3?id=${response2.data.id}`);
console.log("Response 3:", response3.data);
} catch (error) {
console.error("Error during requests:", error);
}
};
fetchSequentialData();
2.使用 Promise 链
import axios from "axios";
axios.get("https://api.example.com/endpoint1")
.then(response1 => {
console.log("Response 1:", response1.data);
return axios.get(`https://api.example.com/endpoint2?id=${response1.data.id}`);
})
.then(response2 => {
console.log("Response 2:", response2.data);
return axios.get(`https://api.example.com/endpoint3?id=${response2.data.id}`);
})
.then(response3 => {
console.log("Response 3:", response3.data);
})
.catch(error => {
console.error("Error during requests:", error);
});
3.使用 for 循环和 async/await
import axios from "axios";
const endpoints = [
"https://api.example.com/endpoint1",
"https://api.example.com/endpoint2",
"https://api.example.com/endpoint3",
];
const fetchSequentially = async () => {
try {
for (const endpoint of endpoints) {
const response = await axios.get(endpoint);
console.log(`Response from ${endpoint}:`, response.data);
}
} catch (error) {
console.error("Error during requests:", error);
}
};
4.使用 async/await 和 Promise.all(最终解决方案)
import axios from "axios";
const endpoints = [
"https://api.example.com/endpoint1",
"https://api.example.com/endpoint2",
"https://api.example.com/endpoint3",
];
const fetchSequentiallyWithAll = async () => {
const results = [];
for (const endpoint of endpoints) {
const response = await axios.get(endpoint); // 按顺序等待每个请求完成
results.push(response.data);
}
// 将所有结果传入 Promise.all 做进一步处理(例如并行保存、进一步请求)
await Promise.all(results.map(data => {
return axios.post("https://api.example.com/save", data); // 示例并行处理
}));
console.log("All data processed.");
};
fetchSequentiallyWithAll();
在使用 Promise.all 时,如果其中一个 Promise 被拒绝(rejected),默认情况下,整个 Promise.all 会立即中止并返回该错误。但在某些场景下,我们希望即使某个接口失败,也不会影响其他接口的执行。
1.在每个接口的 Promise 上调用 .catch 方法捕获错误,这样即使某个接口失败,它也会返回一个被处理的结果,而不会中断整个 Promise.all。
import axios from "axios";
const endpoints = [
"https://api.example.com/endpoint1",
"https://api.example.com/endpoint2",
"https://api.example.com/endpoint3",
];
const fetchWithErrorHandling = async () => {
const promises = endpoints.map(endpoint =>
axios.get(endpoint).catch(error => {
console.error(`Error fetching ${endpoint}:`, error);
return { error: true, endpoint }; // 返回错误信息而不是让 Promise 失败
})
);
const results = await Promise.all(promises);
console.log("Results:", results);
// 结果中包含成功的数据和失败的信息
};
fetchWithErrorHandling();
- 包装每个 Promise 的状态 将每个 Promise 包装成一个始终成功的形式,返回其状态和结果(成功或失败),这样可以在结果中区分成功和失败的情况。 3.用 Promise.allSettled(推荐方法) Promise.allSettled 是专门为这种场景设计的。它会等待所有 Promise 完成,无论是成功还是失败,并返回每个 Promise 的状态和结果。
import axios from "axios";
const fetchAllWithSettled = async () => {
const promises = endpoints.map(endpoint => axios.get(endpoint));
const results = await Promise.allSettled(promises);
results.forEach(result => {
if (result.status === "fulfilled") {
console.log("Success:", result.value.data);
} else {
console.error("Failed:", result.reason);
}
});
};
fetchAllWithSettled();