在 Vue3 中,AbortController
用于取消 fetch
请求,避免组件卸载后仍执行异步操作导致的潜在问题(如内存泄漏或更新已销毁组件的状态)。以下是详细用法和最佳实践:
一、基本用法
-
创建
AbortController
实例
在组件setup()
中创建实例,并通过signal
关联请求:javascript
import { onUnmounted } from 'vue';export default {setup() {const controller = new AbortController();const signal = controller.signal;// 发送请求时传递 signalfetch('/api/data', { signal }).then(response => response.json()).catch(err => {if (err.name === 'AbortError') {console.log('请求已取消');} else {console.error('请求失败:', err);}});// 组件卸载时取消请求onUnmounted(() => controller.abort());return {};}, };
二、结合异步操作
在异步函数中结合 AbortController
:
javascript
import { onUnmounted } from 'vue';export default {setup() {const controller = new AbortController();const fetchData = async () => {try {const response = await fetch('/api/data', { signal: controller.signal });const data = await response.json();// 处理数据} catch (err) {if (err.name === 'AbortError') {console.log('请求已取消');} else {console.error('请求失败:', err);}}};fetchData();onUnmounted(() => controller.abort());}, };
三、管理多个请求
单个 AbortController
可取消多个请求:
javascript
const controller = new AbortController();// 请求1 fetch('/api/data1', { signal: controller.signal });// 请求2 fetch('/api/data2', { signal: controller.signal });// 取消所有请求 controller.abort();
四、与 Axios 结合使用
如果使用 Axios,可通过 CancelToken
(旧版)或 AbortController
(Axios >= 0.22.0)取消请求:
javascript
import axios from 'axios';const controller = new AbortController();axios.get('/api/data', {signal: controller.signal, }).then(response => { /* ... */ }).catch(err => {if (axios.isCancel(err)) {console.log('请求已取消');}});// 取消请求 controller.abort();
五、注意事项
-
兼容性
AbortController
在现代浏览器中支持良好,但需考虑旧版浏览器兼容性(可通过polyfill
解决)。 -
错误处理
捕获AbortError
避免未处理的 Promise 拒绝。 -
复用 Controller
每次新请求前创建新的AbortController
,避免重复使用已取消的实例。
六、最佳实践
-
在组件卸载时取消请求:在
onUnmounted
生命周期钩子中调用abort()
。 -
封装可复用的逻辑:将取消逻辑封装到自定义 Hook 中(如
useFetch
)。 -
避免内存泄漏:确保所有未完成的请求在组件销毁时被取消。
通过合理使用 AbortController
,可以有效管理 Vue3 中的异步操作,提升应用性能和稳定性。