主要用途
AbortController
是一个 Web API,主要用于取消一个或多个 Web 请求(如 fetch 请求)或终止其他异步操作。它提供了一种标准化的方式来中断正在进行的操作,特别是在以下情况下非常有用:
- 用户离开页面或切换视图时取消未完成的网络请求
- 实现超时机制
- 取消不再需要的长时间运行的操作
- 避免竞态条件(race conditions)
基本工作原理
AbortController
的工作原理基于以下组件:
- AbortController:控制器对象,用于创建中止信号并触发中止操作
- AbortSignal:表示中止状态的信号对象,可以传递给支持中止的 API
基本用法示例
// 创建一个 AbortController 实例
const controller = new AbortController();
// 获取与控制器关联的信号
const signal = controller.signal;
// 使用 fetch API 并传入信号
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
// 当请求被中止时,错误类型为 AbortError
if (err.name === 'AbortError') {
console.log('Fetch request was aborted');
} else {
console.error('Fetch error:', err);
}
});
// 在需要时中止请求
// 例如:用户点击取消按钮、设置超时等
controller.abort();
高级用例
1. 实现请求超时
function fetchWithTimeout(url, options = {}, timeout = 5000) {
const controller = new AbortController();
const { signal } = controller;
// 设置超时
const timeoutId = setTimeout(() => controller.abort(), timeout);
return fetch(url, { ...options, signal })
.then(response => {
clearTimeout(timeoutId);
return response;
})
.catch(err => {
clearTimeout(timeoutId);
throw err;
});
}
// 使用
fetchWithTimeout('https://api.example.com/data', {}, 3000)
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Request timed out');
} else {
console.error(err);
}
});
2. 取消多个请求
const controller = new AbortController();
const { signal } = controller;
// 多个使用同一信号的请求
Promise.all([
fetch('/api/data1', { signal }),
fetch('/api/data2', { signal }),
fetch('/api/data3', { signal })
])
.then(responses => Promise.all(responses.map(r => r.json())))
.then(dataArray => console.log(dataArray))
.catch(err => {
if (err.name === 'AbortError') {
console.log('All requests were aborted');
}
});
// 一次调用可以取消所有请求
controller.abort();
3. 与其他异步 API 一起使用
// 与 DOM API 一起使用
const controller = new AbortController();
const { signal } = controller;
document.addEventListener('mousemove', event => {
console.log(event.clientX, event.clientY);
}, { signal });
// 稍后取消事件监听
controller.abort();
浏览器支持
AbortController
在所有现代浏览器中得到广泛支持,包括:
- Chrome 66+
- Firefox 57+
- Safari 12.1+
- Edge 16+
对于不支持的浏览器,可以使用 polyfill。
总结
AbortController
是一个强大的 Web API,专门用于:
- 取消进行中的网络请求
- 停止不再需要的异步操作
- 实现请求超时逻辑
- 防止竞态条件
- 在用户交互变化时优雅地处理资源清理
它提供了一种标准且优雅的方式来管理异步操作的生命周期,特别是在单页应用程序中,对于提高用户体验和资源利用效率非常重要。