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

查询

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

查询基础

查询是对异步数据源的一种声明式依赖,它与一个唯一键相关联。查询可用于任何基于 Promise 的方法(包括 GET 和 POST 方法)以从服务器拉取数据。如果你的方法会修改服务器上的数据,我们建议改用修改。

要在组件或服务中订阅一个查询,请调用 injectQuery,至少传入以下两项参数:

  • 该查询的唯一键
  • 一个返回 Promise 或 Observable 的函数,该函数:
    • 成功解析出数据,或
    • 抛出错误
TypeScript
1import { injectQuery } from '@tanstack/angular-query-experimental'2 3export class TodosComponent {4  readonly todosQuery = injectQuery(() => ({5    queryKey: ['todos'],6    queryFn: fetchTodoList,7  }))8}

你提供的唯一键会在内部用于重新拉取、缓存以及在整个应用中共享该查询。

injectQuery 返回的查询结果对象包含了你在模板渲染及其他数据使用场景中所需的所有查询信息:

TypeScript
1todosQuery = injectQuery(() => ({2  queryKey: ['todos'],3  queryFn: fetchTodoList,4}))

result 对象包含若干关键状态,你必须了解这些状态才能高效使用。在任意时刻,查询仅可能处于以下状态之一:

  • isPending 或 status === 'pending' —— 查询尚无数据
  • isError 或 status === 'error' —— 查询发生错误
  • isSuccess 或 status === 'success' —— 查询成功,数据可用

除上述主要状态外,还可根据查询当前所处状态获取更多信息:

  • error —— 若查询处于 isError 状态,则可通过 error 属性获取错误信息。
  • data —— 若查询处于 isSuccess 状态,则可通过 data 属性获取数据。
  • isFetching —— 在任何状态下,只要查询正在拉取(包括后台重新拉取),isFetching 均为 true。

对于大多数查询,通常只需依次检查 isPending 状态、再检查 isError 状态,最后即可默认数据已就绪并渲染成功状态:

angular-ts
1@Component({2  selector: 'todos',3  template: `4    @if (todosQuery.isPending()) {5      <span>Loading...</span>6    } @else if (todosQuery.isError()) {7      <span>Error: {{ todosQuery.error()?.message }}</span>8    } @else {9      <!-- We can assume by this point that status === 'success' -->10      @for (todo of todosQuery.data(); track todo.id) {11        <li>{{ todo.title }}</li>12      } @empty {13        <li>No todos found</li>14      }15    }16  `,17})18export class PostsComponent {19  readonly todosQuery = injectQuery(() => ({20    queryKey: ['todos'],21    queryFn: fetchTodoList,22  }))23}

若你不习惯使用布尔值判断,也可直接使用 status 状态:

angular-ts
1@Component({2  selector: 'todos',3  template: `4    @switch (todosQuery.status()) {5      @case ('pending') {6        <span>Loading...</span>7      }8      @case ('error') {9        <span>Error: {{ todosQuery.error()?.message }}</span>10      }11      <!-- also status === 'success', but "else" logic works, too -->12      @default {13        <ul>14          @for (todo of todosQuery.data(); track todo.id) {15            <li>{{ todo.title }}</li>16          } @empty {17            <li>No todos found</li>18          }19        </ul>20      }21    }22  `,23})24class TodosComponent {}

若你在访问 data 前已检查过 pending 和 error,TypeScript 也会正确地收窄 data 的类型。

FetchStatus

除 status 字段外,你还将获得一个额外的 fetchStatus 属性,其取值如下:

  • fetchStatus === 'fetching' —— 查询当前正在拉取。
  • fetchStatus === 'paused' —— 查询本应拉取,但已被暂停。更多细节请参阅网络模式指南。
  • fetchStatus === 'idle' —— 查询当前未执行任何操作。

为何需要两种不同状态?

后台重新拉取与“过期时验证”(stale-while-revalidate)逻辑使得 status 和 fetchStatus 的所有组合均可能发生。例如:

  • 处于 success 状态的查询通常对应 idle fetchStatus,但如果正发生后台重新拉取,则也可能为 fetching。
  • 一个刚挂载且尚无数据的查询通常处于 pending 状态和 fetching fetchStatus,但在无网络连接时也可能为 paused。

因此请牢记:查询可能处于 pending 状态却并未实际拉取数据。经验法则是:

  • status 表示关于 data 的信息:我们是否有数据?
  • fetchStatus 表示关于 queryFn 的信息:它是否正在运行?

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

译自上游 59d11de