实际项目需求,类似机器人对话。生成对话过程中有个停止生成。点击停止生成中断请求。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 }
}