vue3 axios封装接口请求 useAxiosWithCancel hook

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

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

从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求:(官方推荐使用)

AbortController(中止控制器)作用和使用

  • AbortController 接口代表一个控制器对象,允许您在需要时中止一个或多个 Web 请求

创建构造函数AbortController()

let controller = new AbortController()

实例属性

AbortController.signal 只读
返回一个 AbortSignal 对象实例,该实例可用于与异步操作通信或中止异步操作。

const { signal } = controller

实例方法

在异步操作完成之前中止该操作。这能够中止获取请求、任何响应主体和流的消耗。

controller.abort() //在异步操作完成之前中止该操作。这能够中止获取请求、任何响应主体和流的消耗。

代码两种终止示例

创建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 }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值