3 回答

TA貢獻1818條經(jīng)驗 獲得超3個贊
限制axios請求本身很容易。真正令人頭疼的是如何處理從無效請求返回的承諾。在處理從無效的axios請求返回的承諾時,什么被認為是理智的行為?他們應該永遠待命嗎?
對于此問題,我看不到任何完美的解決方案。但是后來我得出了一種作弊的解決方案:
如果我們不限制axios調(diào)用,而是限制實際的XMLHttpRequest怎么辦?
這使事情變得更容易,因為它避免了promise問題,并且更易于實現(xiàn)。想法是為最近的請求實現(xiàn)緩存,如果新請求與最近的請求匹配,則只需從緩存中提取結果,然后跳過XMLHttpRequest。
由于axios攔截器的工作方式,以下代碼段可用于有條件地跳過某些XHR調(diào)用:
// 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條經(jīng)驗 獲得超5個贊
也許您可以嘗試使用axios提供的“取消”功能。
使用它,您可以確保在掛起狀態(tài)中沒有任何兩個(或更多,取決于實現(xiàn))類似的請求。
在下面,您將找到一個簡化的小示例,該示例演示如何確保僅處理最新的請求。您可以對其進行一些調(diào)整以使其像請求池一樣起作用
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;
添加回答
舉報