AbortController的基本使用
1.AbortController的简介
AbortController是一种用于管理和控制 Web API 中异步操作(如fetch请求)的取消操作的机制。它在处理异步操作时提供了一种方法来中止未完成的请求或操作。AbortController是一个浏览器原生对象,它允许你创建和控制一个或多个异步操作的取消信号。通过与AbortSignal结合使用,可以在适当的时机中止这些操作。
2.AbortController 的组成部分
AbortController对象:用来创建和控制取消操作。AbortSignal对象:由AbortController生成,用来向异步操作传递取消信号。
3.创建AbortController的实例
const controller = new AbortController(
- 在如上代码中,
controller是AbortController的实例。你可以使用它来生成一个信号,传递给支持取消操作的 API(如fetch),并在适当的时候通过abort()方法取消这些操作。 new AbortController():创建一个新的AbortController实例。controller:是创建的AbortController实例,它包含一个signal属性和一个abort()方法。
4.AbortController 的基本使用
const controller = new AbortController(); // 创建一个新的 AbortController 实例
const signal = controller.signal; // 获取该实例的 signal
// 发起一个带有信号的 fetch 请求
fetch('https://api.example.com/data', { signal }).then(response =>
response.json()
).then(data =>
console.log(data)
).catch(err => {
if (err.name === 'AbortError') {
console.log('请求已被中止');
} else {
console.error('请求失败:', err);
}
});
// 在某个条件下中止请求
controller.abort(); // 调用 abort() 方法,中止请求
5.AbortController 的重要方法和属性
-
controller.signal:- 这是一个
AbortSignal对象,它与异步操作关联,传递给像fetch这样的支持中止的 API。 - 你需要将这个
signal传递给异步操作,以便在后续通过AbortController中止该操作。
- 这是一个
-
controller.abort():- 通过调用
abort()方法,可以触发与该signal关联的异步操作的中止。对于fetch请求来说,这意味着请求将被中止,并抛出一个AbortError。
- 通过调用
6.使用场景
-
取消请求:在用户离开页面、导航到新页面、或在短时间内多次发起请求时,避免处理不必要的响应。
-
超时机制:如果一个请求持续时间过长,可以设置一个超时机制,在超时后中止请求。
vue3.5新特性+AbortController(Web Api)封装请求函数
使用 Vue 3.5 中新增的 onWatcherCleanup 和 getCurrentWatcher 函数,你可以封装一个可以在 watch 中安全使用的 fetch 函数。 该函数会在执行 watch 的回调函数之前取消之前的请求。
// myFetch.ts
import { onWatcherCleanup, getCurrentWatcher } from 'vue'
export function myFetch(url: string, options: RequestInit) {
// 创建一个新的 AbortController 实例
const controller = new AbortController()
// 获取该实例的 signal
const signal = controller.signal
if(getCurrentWatcher()) {
onWatcherCleanup(() => {
controller.abort()
})
}
return fetch(url, { ...options, signal })
}
// xxx.vue
<script setup>
watch(id, (newId) => {
myFetch(`/api/${newId}`).then((response) => {
// callback logic
})
})
</script>