受到这篇文章的启发,DrewReese提供了一个关于如何保持价值的答案使用refs取消API请求时。这个解决方案对给定的问题很有效。这是一个需要解决的边缘情况。
假设您有一个下载按钮,用户可以在其中从服务器下载文件。当用户点击下载按钮时,会打开一个显示下载进度的模式(使用Axios OnDownloadprogress)。模态有一个关闭按钮,用来取消API请求。因为没有重新渲染组件,所以AbortSignal的值仍然是相同的。这将导致当用户再次单击下载按钮时,随后的下载将被终止。
AbortController ref
let controller = useRef(new AbortController()).current;
关闭模态并终止请求的函数
const closeModal = () => {
//close modal logic
controller.abort()
}
API请求函数
const downlodFile = async (type) => {
//some logic
const res = await axios({
url: "https://www.something.com",
onDownloadProgress: (progressEvent) => {
//some calculations
},
signal: controller.signal
})}
重新提交请求,在abort
之后创建一个AbortController类的新实例const cancelFn = function () {
controller.abort();
controller = new AbortController;
};
完整代码:
window.addEventListener('load', function () {
const exportBtn = document.querySelector('.export-data-link');
const cancelBtn = document.querySelector('.export-data-cancel');
const infoPlace = document.querySelector('.export-data-info');
var controller = new AbortController;
exportBtn.addEventListener('click', function (event) {
infoPlace.style.display = 'inline';
const request = new Request(event.target.dataset.href, { signal: controller.signal });
fetch(request)
.then(function (response) {
if (response) return response.blob();
})
.finally(function () {
infoPlace.style.display = 'none'
})
.then(function (blob) {
if (blob) window.location.assign(window.URL.createObjectURL(blob));
})
.catch(function (error) {
});
});
const cancelFn = function () {
controller.abort();
controller = new AbortController;
};
cancelBtn.addEventListener('click', cancelFn);
});