1. fetch XHR 请求的主动中断
1.1 使用 AbortController
fetch 原生支持 AbortController 来中断请求。
示例代码
// 创建一个 AbortController 实例
const controller = new AbortController();
const signal = controller.signal;
// 发起 fetch 请求时传入 signal
fetch('https://jsonplaceholder.typicode.com/todos/1', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被中断');
} else {
console.error('请求出错', err);
}
});
// 需要中断请求时调用
controller.abort();
2. axios XHR 请求的主动中断
2.1 使用 CancelToken(axios v0.22及以下)
import axios from 'axios';
const CancelToken = axios.CancelToken;
let cancel;
// 发起请求
axios.get('https://jsonplaceholder.typicode.com/todos/1', {
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).then(res => {
console.log(res.data);
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log('请求被取消');
} else {
console.error('请求出错', thrown);
}
});
// 需要中断请求时调用
cancel('手动取消请求');
2.2 axios v1.0+ 推荐用 AbortController
const controller = new AbortController();
axios.get('https://jsonplaceholder.typicode.com/todos/1', {
signal: controller.signal
}).then(res => {
console.log(res.data);
}).catch(err => {
if (err.code === 'ERR_CANCELED') {
console.log('请求被取消');
} else {
console.error('请求出错', err);
}
});
// 需要中断请求时调用
controller.abort();
3. SSE(Server-Sent Events)请求的主动中断
SSE 通常用 EventSource 或自定义 fetch+流的方式实现。
3.1 原生 EventSource
const es = new EventSource('/sse-url');
es.onmessage = (event) => {
console.log('收到消息:', event.data);
};
// 需要中断时
es.close();
3.2 fetch+流(如你的 MyStream 实现)
你需要保存 AbortController 实例,并在需要时调用 abort()。
伪代码示例
class MyStream {
constructor() {
this.controller = null;
this.reader = null;
}
async getStream(url, onData, onEnd) {
this.controller = new AbortController();
const response = await fetch(url, { signal: this.controller.signal });
const reader = response.body.getReader();
this.reader = reader;
// 读取流数据
while (true) {
const { value, done } = await reader.read();
if (done) break;
onData(value);
}
onEnd();
}
abortStream() {
if (this.reader) this.reader.cancel();
if (this.controller) this.controller.abort();
}
}
// 使用
const stream = new MyStream();
stream.getStream('/sse-url', data => console.log(data), () => console.log('end'));
// 需要中断时
stream.abortStream();
4. 结合 Vue 组件的实际用法
data() {
return {
controller: null,
}
},
methods: {
fetchData() {
this.controller = new AbortController();
fetch('/api/data', { signal: this.controller.signal })
.then(res => res.json())
.then(data => { /* ... */ })
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被中断');
}
});
},
abortFetch() {
if (this.controller) this.controller.abort();
}
}
总结
- fetch/axios v1+ 推荐用
AbortController,调用controller.abort()主动中断。 - axios v0.22- 用
CancelToken。 - SSE 用
EventSource.close()或自定义流时用AbortController和reader.cancel()。 - 高频请求场景,一定要保存 controller/reader 实例,及时中断不再需要的请求,避免资源泄漏和页面卡死。
如需结合你项目的具体代码进一步优化,请补充说明!