axios 取消请求操作

193 阅读1分钟

axios 取消请求操作

1.需求背景: 请求操作特别频繁时, 由于触发了多个请求, 不确定哪一个请求能优先回来, 导致 数据不一致

大致效果图 image.png

  1. 核心代码(3种方式, 推荐 AbortController)
  1. AbortController (Axios 0.22.0 )之后支持
  2. const controller = new AbortController()
  3. axios.get('x/xx', { signal: controller.signal }) 请求配置
  4. 取消操作controller.abort()
  5. CancelToken(Axios 0.22.0)之后弃用
  6. const CancelToken = axios.CancelToken const source = CancelToken.source()
  7. axios.get('x/xx', {cancelToken: source.token})
  8. 取消操作 source.cancel('Operation canceled by the user') message 可选
  9. CancelToken 构造函数
  10. let cancel = null 定义变量
  11. const cancelToken =axios.canclToken
  12. axios.get('x/xx', cancelToken: new CancelToken((c) => cancel = c))
  13. 取消操作 cancel()

代码示例:


<script lang="ts" setup>
import { getCurrentInstance, ref, watch } from 'vue'
import { getNewList } from './api';
import Axios, { Canceler, CancelTokenSource } from 'axios';
const CancelToken = Axios.CancelToken

// 用于取消请求
const testCancel = ref< CancelTokenSource | null>(null)

// 方式1
const sendPost = () => {
  try {
    // 重复操作时, 取消之前的发送
    testCancel.value && testCancel.value.cancel()
    // 生成新的 source
    const source = CancelToken.source()
    // 重新赋值
    testCancel.value = source
     // 发送请求
    getNewList({cancelToken: source.token})
  } catch (error) {
    
  }
}

// 方式 2
const testCancel = ref<Canceler | null>(null)

const sendPost = async () => {
  try {
    // 重复操作时, 取消之前的发送
    testCancel.value && testCancel.value()
    // 重新赋值 
    const res = await getNewList({cancelToken: new CancelToken(c => testCancel.value = c)})
    console.log(res);
  } catch (error) {
    
  }
}

// 方式 3 (版本 大于等于 0.22.0)
const testCancel = ref<AbortController | null>(null)

const sendPost = async () => {
  // newListStore.getNewList(100, newListStore.states)
  try {
    // 重复操作时, 取消之前的发送
    testCancel.value && testCancel.value.abort()
    // 生成新的 controlLer
    const controlLer = new AbortController()
    // 重新赋值 
    testCancel.value = controlLer
    const res = await getNewList({signal: controlLer.signal})

    console.log(res);
    
  } catch (error) {
    
  }
}
</script>

<template>
  <input type="text" @input="sendPost">
</template>

<style scoed lang="less"></style>

api.js

/**
 * options axios 额外的配置
 * @param options 
 */
export const getNewList = (options: any) => {
    return axios({
      method: 'GET',
      url: 'http://geek.itheima.net/v1_0/articles',
      params: {
        channel_id: 100,
        timestamp: Date.now()
      },
      ...options
    })
}