axios 正在重置AbortController的值

lmvvr0a8  于 2023-01-20  发布在  iOS
关注(0)|答案(1)|浏览(143)

受此启发,DrewReese提供了一个解决方案,可以在使用refs取消API请求时持久保存AbortController的值。该解决方案对给定问题很有效。下面是一个需要解决的边缘情况。
假设您有一个下载按钮,用户可以在其中从服务器下载文件。当用户单击下载按钮时,将打开一个显示下载进度的模态(使用Axios OnDownloadprogress)。模态有一个关闭按钮,用于取消API请求。问题出现的原因是组件没有重新呈现,AbortSignal的值仍然是相同的。2这会导致当用户再次点击下载按钮时,后续的下载被终止。
中止控制器参考

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
                               })}
okxuctiv

okxuctiv1#

要重新提交请求,请在中止后创建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);
});

相关问题