译零 TransZero · TanStack Query 中文文档
主站

查询取消

更新于 2026-11-02 Angular 查看英文原文 ↗

TanStack Query 会为每个查询函数提供一个 AbortSignal 实例。当查询变为过期或非活跃状态时,该 signal 将被中止。这意味着所有查询均可取消,且你可根据需要在查询函数内部响应取消操作。最棒之处在于,你得以继续使用常规的 async/await 语法,同时获得自动取消的所有优势。

默认行为

默认情况下,若查询在 Promise 解析完成前已卸载(unmount)或不再被使用,则 不会 被取消。这意味着一旦 Promise 解析完成,所得数据将存入缓存。当你已发起某个查询,但组件在查询完成前即被卸载时,此行为十分有用:若之后再次挂载该组件,且该查询尚未被垃圾回收,则数据仍可立即使用。

然而,若你在查询函数中使用了 AbortSignal,则 Promise 将被取消(例如中止 fetch 请求),因此该查询也必须被取消。取消查询会导致其状态 回滚 至此前状态。

使用 HttpClient

TypeScript
1import { injectQuery } from '@tanstack/angular-query-experimental'2import { fromEvent, lastValueFrom, takeUntil } from 'rxjs'3 4postQuery = injectQuery(() => ({5  queryKey: ['post', this.postId()],6  queryFn: (context): Promise<Post> => {7    const abort$ = fromEvent(context.signal, 'abort')8    return lastValueFrom(this.getPost$(this.postId()).pipe(takeUntil(abort$)))9  },10}))

使用 fetch

TypeScript
1todosQuery = injectQuery(() => ({2  queryKey: ['todos'],3  queryFn: async ({ signal }) => {4    const todosResponse = await fetch('/todos', {5      // Pass the signal to one fetch6      signal,7    })8    const todos = await todosResponse.json()9 10    const todoDetails = todos.map(async ({ details }) => {11      const response = await fetch(details, {12        // Or pass it to several13        signal,14      })15      return response.json()16    })17 18    return Promise.all(todoDetails)19  },20}))

使用 axios

TypeScript
1import axios from 'axios'2 3const todosQuery = injectQuery(() => ({4  queryKey: ['todos'],5  queryFn: ({ signal }) =>6    axios.get('/todos', {7      // Pass the signal to `axios`8      signal,9    }),10}))

手动取消

你可能需要手动取消某个查询。例如,若请求耗时较长,你可以允许用户点击取消按钮来中止请求。为此,只需调用 queryClient.cancelQueries({ queryKey }),该方法将取消查询并使其状态回滚至此前状态。若你已在查询函数中使用了传入的 signal,TanStack Query 还会额外取消该 Promise。

angular-ts
1@Component({2  template: `<button (click)="onCancel()">Cancel</button>`,3})4export class TodosComponent {5  readonly todosQuery = injectQuery(() => ({6    queryKey: ['todos'],7    queryFn: async ({ signal }) => {8      const resp = await fetch('/todos', { signal })9      return resp.json()10    },11  }))12 13  readonly queryClient = inject(QueryClient)14 15  onCancel() {16    this.queryClient.cancelQueries({ queryKey: ['todos'] })17  }18}

本页为 TanStack Query 文档(Angular 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de