实际项目需求,类似机器人对话。生成对话过程中有个停止生成。点击停止生成中断请求。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 = nullconst query = ref(queryFactory())const queryAPI = ref(searchAPI)const fetchData = async (data) => {cancelRequest() // 先取消之前的请求query.value = { ...query.value, ...data }loading.value = truecancelTokenSource = 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.dataerror.value = nullconst res = response.dataonSuccess(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 }
}