摆脱异步烦恼的响应式数据

发布: (2026年3月5日 GMT+8 07:06)
4 分钟阅读
原文: Dev.to

Source: Dev.to

Robert Sanders

现代前端开发常常变成与异步代码的搏斗:

  • async/await
  • 订阅
  • 依赖数组
  • 记忆化
  • 竞争条件
  • 不必要的重新计算

如果你只需要描述你的数据,让系统自行处理其余工作,会怎样?

这正是 rs‑x 背后的理念。

为了演示,我做了一个小 demo,用来实时跟踪国际空间站(ISS)的位置。

👉 在线演示:


思路

演示程序轮询公共 ISS API,并将数据作为 reactive model(响应式模型)的一部分公开。

⚠️ 注意: 如果大量用户同时打开演示,公共 ISS API 可能会因速率限制而返回 Too Many Requests(请求过多)错误。

API 返回:

  • timestamp(时间戳)
  • latitude(纬度)
  • longitude(经度)
  • altitude(高度)
  • velocity(速度)

与此同时,模型中包含一个 expensive computation(耗时计算),用于演示 rs‑x 如何处理依赖关系。

核心思路: 只重新计算实际依赖于已更改数据的部分。

演示

该 API 每隔几秒使用 RxJS 轮询一次。

const $ = api.rxjs;
const rsx = api.rsx;

const issRaw$ = $.interval(2000).pipe(
  $.startWith(0),
  $.switchMap(() =>
    $.from(
      fetch('https://api.wheretheiss.at/v1/satellites/25544')
        .then(r => r.json())
    )
  ),
  $.map(data => ({
    ts: Number(data.timestamp ?? 0),
    lat: Number(data.latitude ?? NaN),
    lon: Number(data.longitude ?? NaN),
    altKm: Number(data.altitude ?? NaN),
    velKph: Number(data.velocity ?? NaN),
  })),
  $.shareReplay({ bufferSize: 1, refCount: true })
);

派生的响应式数据

接下来我们派生一个流,仅在国际空间站(ISS)位置有意义变化时发出。

const geoInputs$ = issRaw$.pipe(
  $.map(x => ({
    latQ: Math.round(x.lat * 100) / 100,
    lonQ: Math.round(x.lon * 100) / 100,
  })),
  $.distinctUntilChanged(
    (a, b) => a.latQ === b.latQ && a.lonQ === b.lonQ
  )
);

这可以防止不必要的重新计算。

响应式模型

const model = {
  iss: issRaw$,
  geo: geoInputs$,

  heartbeat: 0,
  expensiveRuns: 0,

  // Expensive computation
  expensiveGeoScore(lat, lon) {
    model.expensiveRuns++;

    let acc = 0;
    for (let i = 0; i  {
  model.heartbeat++;
}, 5000);
  • 进入全屏模式
  • 退出全屏模式

不会触发昂贵的计算
为什么?因为该表达式仅依赖于:

  • geo.latQ
  • geo.lonQ

rs‑x 会自动跟踪这些依赖。

为什么这很重要

在许多系统中,你需要手动管理重新计算:

  • useMemo
  • useEffect
  • 依赖数组
  • 缓存
  • 手动优化

使用 rs‑x,规则很简单:描述你的数据及其关系
运行时会构建一个 reactive dependency graph,并仅重新计算所需的部分。


心智模型

把它想象成电子表格。如果单元格 A1 发生变化:

  • 只有依赖 A1 的单元格会更新
  • 不相关的单元格保持不变

rs‑x 将此模型引入 JavaScript 表达式

结果

演示创建了一个 响应式计算图,它:

  • 处理异步流
  • 自动跟踪依赖
  • 避免不必要的重新计算
  • 使代码保持声明式且简洁

没有异步编排。
没有手动依赖跟踪。
只需描述数据。

支持项目

如果您喜欢 rs‑x,考虑支持该项目:

GitHub Sponsors – robert‑sanders‑software‑ontwikkeling

这有助于我继续为开发者构建 开源工具


标签

javascript #reactiveprogramming #rxjs #opensource #webdevelopment

0 浏览
Back to Blog

相关文章

阅读更多 »