Skip to content

取消请求方式


  1. XMLHttpRequest 的 abort()
javascript
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.send();

// 取消请求
xhr.abort();
  1. Fetch 配合 AbortController
javascript
const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => response.json())
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('请求被取消');
    }
  });

// 取消请求
controller.abort();
  1. Axios 取消请求

方式一:使用 CancelToken(旧版本)

javascript
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('https://api.example.com/data', {
  cancelToken: source.token
});

// 取消请求
source.cancel('请求被用户取消');

方式二:使用 AbortController(新版本)

javascript
const controller = new AbortController();

axios.get('https://api.example.com/data', {
  signal: controller.signal
});

// 取消请求
controller.abort();
  1. React Query 取消请求
javascript
const { refetch } = useQuery('key', fetchFn, {
  enabled: false
});

// 组件卸载时自动取消
useEffect(() => {
  const promise = refetch();
  
  return () => {
    // 取消请求
    promise.cancel();
  };
}, []);
  1. 应用场景

搜索防抖时取消上一次请求:

javascript
let controller = null;

const search = async (keyword) => {
  // 取消之前的请求
  if (controller) {
    controller.abort();
  }
  
  // 创建新的 controller
  controller = new AbortController();
  
  try {
    const response = await fetch(`/api/search?q=${keyword}`, {
      signal: controller.signal
    });
    const data = await response.json();
    return data;
  } catch (err) {
    if (err.name === 'AbortError') {
      console.log('搜索请求被取消');
    }
    throw err;
  }
};

组件卸载时取消请求:

javascript
function SearchComponent() {
  useEffect(() => {
    const controller = new AbortController();
    
    const fetchData = async () => {
      try {
        const response = await fetch('/api/data', {
          signal: controller.signal
        });
        const data = await response.json();
        // 处理数据
      } catch (err) {
        if (err.name === 'AbortError') {
          console.log('组件卸载,请求被取消');
        }
      }
    };
    
    fetchData();
    
    // 清理函数
    return () => {
      controller.abort();
    };
  }, []);
  
  return <div>搜索组件</div>;
}

Released under the MIT License.