AbortController

更新于 阅读 5

AbortController 是一个控制器对象,用来中止一个或多个 Web 请求。

比如text/event-stream中,后端会持续给前端推送数据,如果前端想取消请求,就可以使用AbortController

先使用AbortController创建一个控制器:

const controller = new AbortController();

controller的属性和方法如下:

  • AbortController.signal: 返回一个AbortSignal对象,用于将signal和controller与fetch请求相关联,通过调用AbortController.abort()来中止fetch.
  • AbortController.abort(): 终止一个未完成的请求,这能够中止 fetch 请求及任何响应体的消费和流。

下面是一个在线示例:点击“下载”按钮下载视频,“取消下载”将中止下载流程,

可以打开控制台查看网络情况,如果网络很快,可以设置成Slow 3G,可以看到请求被取消了,截图如下:

js代码如下

const url = 'https://vwood.xyz/images/sintel.mp4'; const videoWrapper = document.querySelector('.videoWrapper'); const downloadBtn = document.querySelector('.download'); const abortBtn = document.querySelector('.abort'); const reports = document.querySelector('.reports'); let controller; let progressAnim; let animCount = 0; downloadBtn.addEventListener('click', fetchVideo); abortBtn.addEventListener('click', () => { // 中止请求 controller.abort(); console.log('Download aborted'); downloadBtn.classList.remove('hidden'); }); function fetchVideo() { // 创建controller对象 controller = new AbortController(); const signal = controller.signal; downloadBtn.classList.add('hidden'); abortBtn.classList.remove('hidden'); reports.textContent = '视频下载中...'; fetch(url, { signal // 将 signal 和 controller 与 fetch 请求相关联 }).then((response) => { if (response.status === 200) { setTimeout(() => console.log('Body used: ', response.bodyUsed), 1); return response.blob(); } else { throw new Error('Failed to fetch'); } }).then((myBlob) => { const video = document.createElement('video'); video.setAttribute('controls', ''); video.src = URL.createObjectURL(myBlob); videoWrapper.appendChild(video); videoWrapper.classList.remove('hidden'); abortBtn.classList.add('hidden'); downloadBtn.classList.add('hidden'); reports.textContent = '视频准备完毕'; }).catch((e) => { abortBtn.classList.add('hidden'); downloadBtn.classList.remove('hidden'); reports.textContent = '下载失败: ' + e.message; }) }

浏览器支持情况

目前主流的浏览器都支持AbortController和AbortSignal,正式环境可以使用。