递归 HTTP 请求是指在 VueJS 应用中,一个 HTTP 请求的响应触发另一个 HTTP 请求,形成链式或树状的请求结构。这在处理分页数据、依赖数据或需要连续获取多级资源的场景中非常有用。
async function recursiveFetch(url, results = []) {
try {
const response = await axios.get(url);
const data = response.data;
results.push(...data.items); // 假设是分页数据
if (data.nextPage) {
return recursiveFetch(data.nextPage, results);
}
return results;
} catch (error) {
console.error('请求失败:', error);
throw error;
}
}
// 在Vue组件中使用
export default {
methods: {
async loadAllData() {
try {
const allData = await recursiveFetch('/api/data');
this.dataList = allData;
} catch (error) {
this.error = '加载数据失败';
}
}
},
created() {
this.loadAllData();
}
}
function fetchPaginatedData(url, accumulatedData = []) {
return axios.get(url)
.then(response => {
const data = response.data;
accumulatedData = accumulatedData.concat(data.items);
if (data.nextPage) {
return fetchPaginatedData(data.nextPage, accumulatedData);
}
return accumulatedData;
});
}
// 使用示例
fetchPaginatedData('/api/data')
.then(allData => {
console.log('所有数据:', allData);
})
.catch(error => {
console.error('获取数据出错:', error);
});
原因:没有正确的终止条件或终止条件判断错误
解决方案:
// 确保有明确的终止条件
async function fetchUntilCondition(url, conditionFn) {
const response = await axios.get(url);
if (conditionFn(response.data)) {
return response.data;
}
return fetchUntilCondition(response.data.nextUrl, conditionFn);
}
原因:递归调用积累的调用栈未释放
解决方案:
// 使用尾递归优化
function fetchAll(url, results = []) {
return axios.get(url).then(response => {
const newResults = [...results, ...response.data.items];
return response.data.nextPage
? fetchAll(response.data.nextPage, newResults)
: newResults;
});
}
原因:递归请求发送过快
解决方案:
// 添加延迟
async function fetchWithDelay(url, delay = 500) {
const response = await axios.get(url);
await new Promise(resolve => setTimeout(resolve, delay));
return response;
}
async function recursiveFetch(url) {
const response = await fetchWithDelay(url);
// ...处理逻辑
if (response.data.nextPage) {
return recursiveFetch(response.data.nextPage);
}
}
原因:未正确处理中间请求失败的情况
解决方案:
async function safeRecursiveFetch(url, attempt = 0, maxAttempts = 3) {
try {
const response = await axios.get(url);
if (response.data.nextPage) {
return safeRecursiveFetch(response.data.nextPage);
}
return response.data;
} catch (error) {
if (attempt < maxAttempts) {
console.warn(`请求失败,重试中 (${attempt + 1}/${maxAttempts})`);
await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1)));
return safeRecursiveFetch(url, attempt + 1, maxAttempts);
}
throw error;
}
}
async function controlledRecursiveFetch(urls, concurrency = 3) {
const results = [];
let index = 0;
async function fetchNext() {
if (index >= urls.length) return;
const currentIndex = index++;
try {
const response = await axios.get(urls[currentIndex]);
results[currentIndex] = response.data;
} catch (error) {
results[currentIndex] = { error: error.message };
}
await fetchNext();
}
const workers = Array(concurrency).fill().map(fetchNext);
await Promise.all(workers);
return results;
}
async function* paginatedDataGenerator(startUrl) {
let url = startUrl;
while (url) {
const response = await axios.get(url);
yield response.data.items;
url = response.data.nextPage;
}
}
// 使用示例
async function processAllData() {
const generator = paginatedDataGenerator('/api/data');
for await (const items of generator) {
console.log('处理一批数据:', items);
// 处理数据逻辑
}
}
递归 HTTP 请求是 VueJS 应用中处理复杂数据获取场景的强大工具,合理使用可以大大简化代码逻辑,但需要注意控制递归深度和错误处理,以确保应用的稳定性和用户体验。
没有搜到相关的文章