Довольно просто задушить запрос axios. Настоящая головная боль заключается в том, как обрабатывать обещания, которые возвращаются из этого аннулированного запроса. Каково вменяемое поведение тех обещаний, которые возвращаются из аннулированного запроса axios? Должны ли они оставаться в ожидании навсегда?
Я не вижу идеального решения этой проблемы. Но потом я прихожу к решению, которое вроде как обмануть:
Что если мы не удушим вызов axios, вместо этого мы удушим реальный запрос XMLHttpRequest?
Это значительно облегчает задачу, поскольку позволяет избежать проблем с обещаниями и проще в реализации. Идея состоит в том, чтобы реализовать кэш для недавнего запроса, и если новый запрос совпадает с последним, вы просто извлекаете результат из кэша и пропускаете запрос 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 normalty
* but this time we use an cached response result
**/
if (error.isSkipXHR) {
return requestCache.getCachedResponse(error.request)
}
return Promise.reject(error);
});