如何使用AbortController取消请求

548 阅读1分钟

使用方法

API解读

AbortController是浏览器内置的API,用于构造一个controller实例

我们可以为将controller.signal传入请求函数中,将signal与请求关联起来

然后调用controller.abort()去取消这个请求

以Axios为例,从v0.22.0开始,Axios就支持使用AbortController来取消请求

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});

// 取消请求
controller.abort()

signal也可以传入多个请求函数中,调用abort()的时候就会同时取消这些请求

逻辑封装

在React中使用AbortController时,可以封装hook简化使用

import { useUnmount } from 'ahooks';
import { useRef } from 'react';

export function useAbortController() {
  const controller = useRef<AbortController>(new AbortController());

  useUnmount(() => {
    controller.current.abort();
  });

  return {
    signal: controller.current.signal,
    abort: controller.current.abort,
  };
}

在业务代码中使用useAbortController时,需要注意

调用abort方法前,需要判断当前是否处于请求中的状态

否则可能会抛出错误 Illegal Invocation

import { useRef, useState } from 'react';

export function useData() {
  const loading = useRef<boolean>(false)
  
  const [data, setData] = useState()
  
  const { signal, abort } = useAbortController()
  
  async function getData() {
    if (loading.current) {
      abort()
    }
    try {
      const resp = await axios.get('xxx', { signal })
      loading.current = false
      if (resp.data) {
        setData(resp.data)
      }
    }catch(e) {
      loading.current = false
    }
  }
  
  return {
    data
  }
}

参考资料