3 回答
TA贡献1818条经验 获得超3个赞
限制axios请求本身很容易。真正令人头疼的是如何处理从无效请求返回的承诺。在处理从无效的axios请求返回的承诺时,什么被认为是理智的行为?他们应该永远待命吗?
对于此问题,我看不到任何完美的解决方案。但是后来我得出了一种作弊的解决方案:
如果我们不限制axios调用,而是限制实际的XMLHttpRequest怎么办?
这使事情变得更容易,因为它避免了promise问题,并且更易于实现。想法是为最近的请求实现缓存,如果新请求与最近的请求匹配,则只需从缓存中提取结果,然后跳过XMLHttpRequest。
由于axios拦截器的工作方式,以下代码段可用于有条件地跳过某些XHR调用:
// This should be the *last* request interceptor to add
axios.interceptors.request.use(function (config) {
/* check the cache, if hit, then intentionally throw
* this will cause the XHR call to be skipped
* but the error is still handled by response interceptor
* we can then recover from error to the cached response
**/
if (requestCache.isCached(config)) {
const skipXHRError = new Error('skip')
skipXHRError.isSkipXHR = true
skipXHRError.request = config
throw skipXHRError
} else {
/* if not cached yet
* check if request should be throttled
* then open up the cache to wait for a response
**/
if (requestCache.shouldThrottle(config)) {
requestCache.waitForResponse(config)
}
return config;
}
});
// This should be the *first* response interceptor to add
axios.interceptors.response.use(function (response) {
requestCache.setCachedResponse(response.config, response)
return response;
}, function (error) {
/* recover from error back to normality
* but this time we use an cached response result
**/
if (error.isSkipXHR) {
return requestCache.getCachedResponse(error.request)
}
return Promise.reject(error);
});
TA贡献1876条经验 获得超5个赞
也许您可以尝试使用axios提供的“取消”功能。
使用它,您可以确保在挂起状态中没有任何两个(或更多,取决于实现)类似的请求。
在下面,您将找到一个简化的小示例,该示例演示如何确保仅处理最新的请求。您可以对其进行一些调整以使其像请求池一样起作用
import axios, { CancelToken } from 'axios';
const pendingRequests = {};
const makeCancellable = (headers, requestId) => {
if (!requestId) {
return headers;
}
if (pendingRequests[requestId]) {
// cancel an existing request
pendingRequests[requestId].cancel();
}
const source = CancelToken.source();
const newHeaders = {
...headers,
cancelToken: source.token
};
pendingRequests[requestId] = source;
return newHeaders;
};
const request = ({
url,
method = 'GET',
headers,
id
}) => {
const requestConfig = {
url,
method,
headers: makeCancellable(headers || {}, id)
};
return axios.request(requestConfig)
.then((res) => {
delete pendingRequests[id];
return ({ data: res.data });
})
.catch((error) => {
delete pendingRequests[id];
if (axios.isCancel(error)) {
console.log(`A request to url ${url} was cancelled`); // cancelled
} else {
return handleReject(error);
}
});
};
export default request;
添加回答
举报