Skip to content
On this page

useAbortController

useAbortController 可以用在需要取消之前的请求或放弃之前的操作的场景。

使用

Demo - 丢弃之前的结果

vue
<script setup lang="ts">
import { ref, watch } from 'vue'
import useAbortController from 'ufuse/src/hooks/useAbortController'

const keyword = ref('')
const ac = useAbortController()

function doSomething(keyword: string) {
  return new Promise<string>((resolve) => {
    window.setTimeout(
      () => resolve(`${keyword} responded.`),
      // 模拟一个异步任务
      Math.random() * 1000,
    )
  })
}

watch(keyword, () => {
  // 在每次调用 consume 方法时,都会创建一个新的 signal
  // 且会取消(abort)上一次的 signal
  const { signal } = ac.consume()

  doSomething(keyword.value)
    .then((result) => {
      // 当异步逻辑完成时,检查 signal 是否已经被取消
      if (signal.aborted) {
        // eslint-disable-next-line no-console
        console.log('aborted')
        return
      }
      // eslint-disable-next-line no-console
      console.log(result)
    })
})
</script>

<template>
  <div class="demo">
    <input
      v-model="keyword"
      class="w-full"
      type="text"
      placeholder="这里输入内容"
    >
  </div>
</template>

Demo - 取消之前的请求

vue
<script setup lang="ts">
import { ref, watch } from 'vue'
import useAbortController from 'ufuse/src/hooks/useAbortController'
import axios, { isCancel } from 'axios'

const keyword = ref('')
const ac = useAbortController()

watch(keyword, () => {
  axios.get('https://cdn.bootcdn.net/ajax/libs/vue/3.2.47/vue.global.min.js', {
    params: {
      keyword: keyword.value,
    },
    // 当调用 consume 方法时,会取消上一次请求
    signal: ac.consume().signal,
  })
    .then((result) => {
      // eslint-disable-next-line no-console
      console.log({ result })
    })
    .catch((err) => {
      if (isCancel(err))
        // eslint-disable-next-line no-console
        console.log('aborted')
    })
})
</script>

<template>
  <div class="demo">
    <input
      v-model="keyword"
      class="w-full"
      type="text"
      placeholder="这里输入内容"
    >
  </div>
</template>

贡献者

cuijin
xieyuhang