核心思路
- 封装接口时返回
Promise
和abort
方法 :
为需要支持取消的接口返回一个对象,包含promise
和abort
方法,用户可通过abort
主动中断请求。 - 使用
AbortController
或CancelToken
:- 推荐
AbortController
(浏览器原生 API,兼容性更好)。 - 若使用
axios
的CancelToken
,需额外处理。
- 推荐
实现步骤
1. 封装 Axios 实例
javascript
// 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. 在组件中使用
js
<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:手动触发取消
javascript
// 在用户点击取消按钮时触发
const cancelButton = () => {
abortUsers(); // 主动调用 abort 方法
};
场景 2:防抖/节流中的取消
javascript
// 输入搜索框时,取消之前的请求
let currentAbortFn = null;
const handleSearch = (query) => {
// 取消之前的请求
if (currentAbortFn) currentAbortFn();
const { promise, abort } = api.getUsers({ query });
currentAbortFn = abort;
promise.then((data) => {
// 处理数据
});
};
其他注意事项
-
服务端支持:
- 前端取消请求仅终止浏览器端处理,服务端可能仍在执行 。若需服务端终止操作,需传递唯一标识(如
requestId
)。
- 前端取消请求仅终止浏览器端处理,服务端可能仍在执行 。若需服务端终止操作,需传递唯一标识(如
-
避免重复调用:
- 确保
abort
方法在适当的时候调用(如组件卸载或用户主动操作),避免多次调用。
- 确保
完整封装示例
javascript
// 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
。 - 错误处理时区分取消错误与其他错误。
此方法既保持了接口的灵活性,又实现了对特定请求的精准控制。