onWatcherCleanup、getCurrentWatcher函数封装请求函数

318 阅读2分钟

AbortController的基本使用

1.AbortController的简介

  • AbortController 是一种用于管理和控制 Web API 中异步操作(如 fetch 请求)的取消操作的机制。它在处理异步操作时提供了一种方法来中止未完成的请求或操作。
  • AbortController 是一个浏览器原生对象,它允许你创建和控制一个或多个异步操作的取消信号。通过与 AbortSignal 结合使用,可以在适当的时机中止这些操作。

2.AbortController 的组成部分

  • AbortController对象:用来创建和控制取消操作。
  • AbortSignal对象:由 AbortController 生成,用来向异步操作传递取消信号。

3.创建AbortController的实例

const controller = new AbortController(
  • 在如上代码中,controllerAbortController 的实例。你可以使用它来生成一个信号,传递给支持取消操作的 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>