vue3封装接口请求 useAxiosWithCancel

发布于:2024-06-21 ⋅ 阅读:(128) ⋅ 点赞:(0)

实际项目需求,类似机器人对话。生成对话过程中有个停止生成。点击停止生成中断请求。axios提供两种方法

  • 1 .使用 AbortController
  • 2CancelToken
    取消请求机制说明:

创建CancelToken源:在每个请求发出前,使用CancelToken.source()创建一个新的取消令牌源
关联CancelToken:将新创建的CancelToken源的token属性添加到请求的配置中,作为cancelToken属性。

取消请求:当需要取消一个请求时,通过其唯一标识从cacheRequest中取出对应的取消函数并执行它,从而取消该请求。

/*
 * @Description: 取消请求
 */
import { ref, onUnmounted } from 'vue'
import axios from 'axios'
import qs from 'qs'

import { eventBus } from '@/utils/eventBus.js'
import { noop } from 'lodash-es'

// let controller
const { CancelToken } = axios
export function useAxiosWithCancel({
  searchAPI,
  immediate = true,
  queryFactory = noop,
  errorRequest = noop,
  beforeBuild = noop,
  onSuccess = noop
}) {
  const data = ref(null)
  const error = ref(null)
  const loading = ref(false)
  let cancelTokenSource = null

  const query = ref(queryFactory())
  const queryAPI = ref(searchAPI)

  const fetchData = async (data) => {
    cancelRequest() // 先取消之前的请求
    query.value = { ...query.value, ...data }
    loading.value = true
    cancelTokenSource = CancelToken.source()
    // controller = new AbortController()
    // const { signal } = controller
    // console.log(cancelTokenSource)
    const { token } = cancelTokenSource
    // console.log(token)
    try {
      const response = await axios.post(queryAPI.value, qs.stringify({ ...query.value }), {
        // signal,
        cancelToken: token
      })
      data.value = response.data
      error.value = null
      const res = response.data
      onSuccess(res)
    } catch (err) {
      if (axios.isCancel(err)) {
        console.log('请求被取消:', err.message)
      } else {
        error.value = `请求出错: ${err.message}`
      }
      errorRequest()
    } finally {
    }
  }

  const cancelRequest = () => {
    if (cancelTokenSource) {
      cancelTokenSource.cancel('请求被取消')
      cancelTokenSource = null
    }
    // if (controller) {
    //   controller.abort()
    //   console.log('Download aborted')
    // }
  }

  const setSearchAPI = (newAPI) => {
    queryAPI.value = newAPI
  }

  // 确保取消未完成的请求
  onUnmounted(() => {
    cancelRequest()
  })

  // 如果需要立即执行请求
  if (immediate) {
    fetchData()
  }

  return { fetchData, data, error, loading, cancelRequest, setSearchAPI }
}


网站公告

今日签到

点亮在社区的每一天
去签到