核心思路
- 封裝接口時返回
Promise
和abort
方法:
為需要支持取消的接口返回一個對象,包含promise
和abort
方法,用戶可通過abort
主動中斷請求。 - 使用
AbortController
或CancelToken
:- 推薦
AbortController
(瀏覽器原生 API,兼容性更好)。 - 若使用
axios
的CancelToken
,需額外處理。
- 推薦
實現步驟
1. 封裝 Axios 實例
// src/api/index.js
import axios from 'axios';// 創建 Axios 實例
const instance = axios.create({baseURL: '/api',timeout: 10000,
});// 封裝需要支持取消的接口
export const api = {// 需要支持取消的接口getUsers() {const controller = new AbortController();const { signal } = controller;const promise = instance.get('/users', { signal });return {promise,abort: () => controller.abort(), // 提供 abort 方法};},// 不需要取消的接口getPosts() {return instance.get('/posts');},
};
2. 在組件中使用
<template><div><!-- 組件內容 --></div>
</template><script setup>
import { onBeforeUnmount } from 'vue';
import { api } from '@/api';// 調用支持取消的接口
const { promise: usersPromise, abort: abortUsers } = api.getUsers();// 處理數據
usersPromise.then((response) => {console.log('用戶數據:', response.data);}).catch((error) => {if (error.name === 'AbortError') {console.log('用戶請求被取消');} else {console.error('請求失敗:', error);}});// 在組件卸載時取消請求
onBeforeUnmount(() => {abortUsers(); // 主動取消請求
});
</script>
關鍵點說明
-
返回
Promise
和abort
方法:- 接口函數返回一個對象,包含
promise
和abort
方法。 - 用戶可通過
abort
方法隨時中斷請求。
- 接口函數返回一個對象,包含
-
錯誤處理:
- 捕獲
AbortError
判斷是否為用戶主動取消。
- 捕獲
-
生命周期管理:
- 在
onBeforeUnmount
中調用abort
,確保組件卸載時取消未完成的請求。
- 在
擴展場景
場景 1:手動觸發取消
// 在用戶點擊取消按鈕時觸發
const cancelButton = () => {abortUsers(); // 主動調用 abort 方法
};
場景 2:防抖/節流中的取消
// 輸入搜索框時,取消之前的請求
let currentAbortFn = null;const handleSearch = (query) => {// 取消之前的請求if (currentAbortFn) currentAbortFn();const { promise, abort } = api.getUsers({ query });currentAbortFn = abort;promise.then((data) => {// 處理數據});
};
其他注意事項
-
服務端支持:
- 前端取消請求僅終止瀏覽器端處理,服務端可能仍在執行。若需服務端終止操作,需傳遞唯一標識(如
requestId
)。
- 前端取消請求僅終止瀏覽器端處理,服務端可能仍在執行。若需服務端終止操作,需傳遞唯一標識(如
-
避免重復調用:
- 確保
abort
方法在適當的時候調用(如組件卸載或用戶主動操作),避免多次調用。
- 確保
完整封裝示例
// src/api/index.js
import axios from 'axios';const instance = axios.create({baseURL: '/api',timeout: 10000,
});export const api = {// 需要支持取消的接口getUsers(params) {const controller = new AbortController();const { signal } = controller;const promise = instance.get('/users', {params,signal,});return {promise,abort: () => controller.abort(),};},// 不需要取消的接口getPosts() {return instance.get('/posts');},
};
總結
通過以下步驟實現手動取消接口:
- 在封裝接口時,返回
Promise
和abort
方法。 - 在組件中通過
onBeforeUnmount
或用戶操作調用abort
。 - 錯誤處理時區分取消錯誤與其他錯誤。
此方法既保持了接口的靈活性,又實現了對特定請求的精準控制。