vue3项目如何设置同样的接口第一次请求有效,如果第二次请求同样的接口,则不去请求,因为第一次请求还没有返回数据
在Vue 3项目中,要实现同样的接口在第一次请求未返回结果之前,后续的请求被取消或忽略,你可以使用JavaScript的AbortController
API来取消正在进行的HTTP请求。同时,你可以结合一个缓存机制来存储每个请求的控制器和Promise,以便在需要时能够取消请求或返回已存在的Promise。
以下是一个基于fetch
API和AbortController
的实现示例:
// 创建一个对象来存储每个请求的控制器和Promise
const requestCache = new Map();
async function fetchData(url) {
// 检查请求是否已经在缓存中
if (requestCache.has(url)) {
// 如果在缓存中,直接返回Promise
return requestCache.get(url).promise;
}
// 创建一个新的AbortController
const controller = new AbortController();
const signal = controller.signal;
// 创建一个新的Promise
const promise = fetch(url, { signal })
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.catch(error => {
// 如果错误是由于请求被取消,则可以选择不抛出错误或抛出特定错误
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
throw error;
}
});
// 将控制器和Promise存储到缓存中
requestCache.set(url, { controller, promise });
// 返回Promise
return promise;
}
// 取消请求的函数
function cancelFetch(url) {
if (requestCache.has(url)) {
const { controller } = requestCache.get(url);
controller.abort(); // 取消请求
requestCache.delete(url); // 可选:从缓存中删除已取消的请求
}
}
// 使用示例
fetchData('https://api.example.com/data')
.then(data => console.log(data))
.catch(error => console.error(error));
// 假设在第一次请求完成之前,你尝试再次请求相同的URL
// fetchData('https://api.example.com/data') // 这将不会发起新的请求,而是返回第一次请求的Promise
// 如果你需要取消请求(例如,用户离开了页面)
// cancelFetch('https://api.example.com/data');
注意:
-
在上面的示例中,
fetchData
函数返回的是fetch
调用的Promise,该Promise在内部被缓存。如果相同的URL再次被请求,它将直接返回缓存中的Promise,而不是发起新的请求。 -
AbortController
用于在需要时取消请求。然而,在上面的示例中,我们并没有在代码中显式调用cancelFetch
函数来取消请求,因为我们的目标是防止在第一次请求完成前发起重复的请求。如果你需要在某些情况下取消请求(例如,用户导航离开页面),你可以调用cancelFetch
函数。 -
如果你的应用需要处理大量并发请求,并且每个请求都可能触发多个相同的API调用,你可能需要更复杂的逻辑来确定何时取消请求或更新缓存。
-
如果你使用的是
axios
而不是fetch
,axios
也支持取消请求,但你需要使用axios.CancelToken.source
而不是AbortController
。 -
考虑到内存管理,你可能需要实现一种机制来清理旧的、不再需要的缓存项。这可以通过设置超时、监听路由变化或使用Vue的生命周期钩子来实现。