@equinor/fusion-query

中文文档
7.0.8发布于 2026/11/12ISCTypeScriptES Module近 30 天下载 1.3万

用可观测流和综合事件系统获取和缓存数据

中文使用文档
文档目录25 节
  1. 何时使用
  2. 安装
  3. 快速启动
  4. 核心概念
  5. 查询
  6. 查询客户端
  7. 查询缓存
  8. 查询任务
  9. 配置选项
  10. 队列策略
  11. 快取管理
  12. 变异( 优化更新)
  13. 无效
  14. 自定义缓存验证
  15. 共享缓存
  16. 持续查询
  17. 事件系统
  18. 查询事件
  19. 查询快捷事件
  20. 查询缓存事件
  21. 订阅事件
  22. 反应集成
  23. 运算符
  24. 清理
  25. 子路径导出

@ equinor/ 聚变- query

反应数据取取和缓存库建于RxJS可观测器上,有队列策略,自动重试,以及综合事件系统.

何时使用

使用 @equinor/fusion-query 当您需要时:

  • 用内置缓存获取远程数据, 防止冗余的网络请求
  • 以可配置的队列策略管理同时提出的请求( E)switch, (中文(简体) ), merge, (中文(简体) ), concat(中文(简体) )
  • 以自定义的延迟和计数方式自动重试失败的请求
  • 对记录、调试或遥测的生命周期事件进行查询的反应
  • 通过共享共享在多个消费者之间共享缓存数据 QueryCache
  • 执行乐观的更新和缓存突变

安装

pnpm add @equinor/fusion-query

快速启动

import { Query } from '@equinor/fusion-query';

interface User {
  id: string;
  name: string;
}

const userQuery = new Query<User, { id: string }>({
  client: {
    fn: async (args, signal) => {
      const res = await fetch(`/api/users/${args.id}`, { signal });
      if (!res.ok) throw new Error('Failed to fetch user');
      return res.json();
    },
  },
  key: (args) => args.id,
  expire: 60_000, // cache valid for 60 seconds
});

// Observable usage
userQuery.query({ id: '123' }).subscribe({
  next: (result) => console.log(result.value),
  error: (err) => console.error(err),
});

// Async/await usage
const result = await userQuery.queryAsync({ id: '123' });
console.log(result.value);

核心概念

查询

这个 Query 类是主要切入点。 协调 QueryClient (手取来),a QueryCache (存储结果),和一个队列运算符(控制货币). 何时 query() ,它首先检查缓存;如果存在有效数据,它立即发出。 否则,新抓取将被排队 .

查询客户端

这个 QueryClient 管理获取功能的执行,包括发送请求、处理故障复试和排放生命周期事件。 可以在多个领域共享 Query 实例.

查询缓存

这个 QueryCache 存储以生成缓存密钥键获取结果。 它支持插入,突变,无效,修饰,并重置. 多个 Query 实例可以共享一个用于跨组件数据共享的缓存 .

查询任务

A 类 QueryTask 代表单一的飞行中获取操作。 任务由缓存密钥来分解:如果两个消费者同时请求相同的数据,他们共享相同的任务.

配置选项

这个 QueryCtorOptions 类型定义 a 的所有配置 Query 实例:

选项类型说明
clientQueryClient | { fn, options? }获取函数或已有 QueryClient 实例
key(args) => string从查询参数生成一个唯一的缓存密钥
expirenumber在缓存项被视为 stale 之前的毫秒
validate(entry, args) => boolean自定义用于验证缓存项的功能
cacheQueryCache | QueryCacheCtorArgs共享缓存实例或构建器参数
queueOperator'switch' | 'merge' | 'concat' | fn处理同时提出的请求的战略

队列策略

队列战略确定如何处理多次同时提出的不同数据请求:

  • switch (默认):当新的请求到达时取消活动请求。 最好的搜索 - you - 类型,只有最近的结果才重要.
  • merge: 并行运行所有请求。 最好每个请求都必须独立解决.
  • concat: 队列按顺序请求. 当执行命令重要时最好.
const query = new Query<SearchResult, { term: string }>({
  client: { fn: searchApi },
  key: (args) => args.term,
  queueOperator: 'switch', // cancel stale searches
});

快取管理

变异( 优化更新)

直接更新缓存数据而不进行调试. 这个 mutate 方法返回恢复上一个值的倒数函数:

const undo = userQuery.mutate(
  { id: '123' },
  (current) => ({ value: { ...current!, name: 'Updated Name' }, updated: Date.now() }),
);

// Roll back if the server update fails
try {
  await updateUserOnServer('123', { name: 'Updated Name' });
} catch {
  undo();
}

无效

将特定条目或整个缓存标为 stale, 强制在下一个查询上重排 :

userQuery.invalidate({ id: '123' }); // invalidate one entry
userQuery.invalidate();                // invalidate all entries

自定义缓存验证

以自定义逻辑覆盖默认过期验证 :

const query = new Query<Data, Args>({
  client: { fn: fetchData },
  key: (args) => JSON.stringify(args),
  validate: (entry, args) => {
    // Consider invalid if older than 30 minutes
    return (entry.updated ?? 0) + 30 * 60_000 > Date.now();
  },
});

共享缓存

多个 Query 实例可以共享 a QueryCache 避免在组件之间重复获取:

import { Query } from '@equinor/fusion-query';
import { QueryCache } from '@equinor/fusion-query/cache';

const sharedCache = new QueryCache();

const homepageQuery = new Query({
  client: { fn: fetchPosts },
  cache: sharedCache,
  key: () => 'posts',
});

const sidebarQuery = new Query({
  client: { fn: fetchPosts },
  cache: sharedCache,
  key: () => 'posts', // same key — reuses cached data
});

持续查询

使用 persistentQuery 当 UI 应实时反映缓存突变 。 与 query()在结果公布后完成的, persistentQuery() 随时更新默认的缓存条目, 继续打开订阅并重寄:

userQuery.persistentQuery({ id: '123' }).subscribe((result) => {
  renderUser(result.value); // re-renders on cache mutation
});

事件系统

这个 Query.event$ 可观察的集合事件来自三个来源——"查询"本身,"查询卡通"和"查询卡通"——进入一流,用于监测和调试.

查询事件

活动说明
query_created启动新查询
query_completed查询完成( 从缓存或获取)
query_connected订阅者加入了现有的飞行任务
query_queued处理队列中添加了一个任务
query_aborted一个查询通过 AbortSignal
query_cache_hit找到有效的缓存数据
query_cache_miss没有有效的缓存; 需要获取
query_cache_added获取的数据被写入到缓存
query_job_created创建了新的抓取工作
query_job_selected队列操作员选中了任务
query_job_started一个工作开始执行
query_job_closed工作报名被关闭了
query_job_completed工作完成且结果被缓存
query_job_skipped任务被跳过( 不再被观察到)

查询快捷事件

活动说明
query_client_job_requested请求带参数获取
query_client_job_executing获取已启动的执行
query_client_job_completed成功获取完成
query_client_job_failed获取执行失败
query_client_job_canceled获取已取消
query_client_job_error发生了无法弥补的错误

查询缓存事件

活动说明
query_cache_entry_set设置了缓存项
query_cache_entry_inserted插入了一个新的条目
query_cache_entry_removed已删除一个条目
query_cache_entry_invalidated条目无效
query_cache_entry_mutated一个条目已变异
query_cache_trimmed缓存被修剪了
query_cache_reset缓存被重置

订阅事件

import { filter } from 'rxjs';
import { QueryEvent } from '@equinor/fusion-query';
import { QueryClientEvent } from '@equinor/fusion-query/client';
import { QueryCacheEvent } from '@equinor/fusion-query/cache';

// All events
query.event$.subscribe((event) => console.log(event.type, event));

// Filter by event type
query.event$.pipe(
  filter((event) => event.type === 'query_cache_hit'),
).subscribe((event) => console.log('Cache hit:', event.data));

// Filter by event source using instanceof
const cacheEvents$ = query.event$.pipe(filter((e) => e instanceof QueryCacheEvent));
const clientEvents$ = query.event$.pipe(filter((e) => e instanceof QueryClientEvent));
const queryEvents$ = query.event$.pipe(filter((e) => e instanceof QueryEvent));

反应集成

这个 @equinor/fusion-query/react 子路径导出 useDebounceQuery 在 React 组件中获取已卸载数据的钩 :

import { useDebounceQuery } from '@equinor/fusion-query/react';

function SearchComponent() {
  const [term, setTerm] = useState('');
  const result = useDebounceQuery(myQuery, {
    args: [{ search: term }],
    delay: 300,
  });

  return <input value={term} onChange={(e) => setTerm(e.target.value)} />;
}

运算符

这个 operators namespace 提供 RxJS 操作器工具 :

  • switchQueue: 当新项目到达时取消在建工程(默认策略).
  • mergeQueue: 不取消同时处理项目.
  • concatQueue:按FIFO顺序依次处理项目.
  • queryValue: 提取原始数据 value 从查询结果流,去除元数据.
import { operators } from '@equinor/fusion-query';

query.query({ id: '123' }).pipe(operators.queryValue).subscribe((user) => {
  console.log(user.name); // plain User object, no wrapper
});

清理

总是不订阅查询可观察或调用 complete() 释放资源:

const sub = query.query(args).subscribe((r) => console.log(r));
// Later:
sub.unsubscribe();

// Or dispose the entire Query instance:
query.complete();

子路径导出

路径目录
@equinor/fusion-queryQuery,类型,运算符,事件
@equinor/fusion-query/cacheQueryCache, (中文(简体) ), QueryCacheEvent,缓存类型
@equinor/fusion-query/clientQueryClient, (中文(简体) ), QueryClientError, (中文(简体) ), QueryClientEvent,客户类型
@equinor/fusion-query/operators队列运算符和 queryValue
@equinor/fusion-query/reactuseDebounceQuery 钩子

版本与发布记录

@equinor/fusion-query 共发布 115 个版本,首次发布于 2022/12/01;过去 12 个月发布了 19 个版本。

版本发布日期距今
7.0.8latest2026/11/121 天前
7.0.8-next.0next2026/11/112 天前
7.0.72026/10/1727 天前
7.0.7-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85atrusted-publishing-202610152026/10/1629 天前
7.0.62026/10/121 个月前
7.0.52026/09/012 个月前

其他发布通道:apploader → 5.2.9-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9,cli-search-index → 6.0.2-cli-search-index.0,msal-v5 → 6.0.4-msal-v5.0,trusted-publishing-20261015 → 7.0.7-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85a,next → 7.0.8-next.0。

关于 @equinor/fusion-query 的常见问题

@equinor/fusion-query 是什么?

用可观测流和综合事件系统获取和缓存数据

如何安装 @equinor/fusion-query?

在项目目录运行 npm install @equinor/fusion-query,或使用 pnpm add / yarn add / bun add。

@equinor/fusion-query 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@equinor/fusion-query 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@equinor/fusion-query 可以商用吗?

@equinor/fusion-query 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@equinor/fusion-query 的下载量有多少?

根据 npm 官方下载统计,@equinor/fusion-query 在 2026/10/14 – 2026/11/12 这 30 天内被下载 12,873 次,日均约 429 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@equinor/fusion-query 还在维护吗?

最新版本 7.0.8 发布于 2026/11/12(1 天前);至今共发布 115 个版本,其中过去 12 个月发布了 19 个;首次发布于 2022/12/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。