在快速写入后, observeCount() 可能仍然过时

作者: codeCraft-Ritik创建于 2026年8月24日更新于 2026年8月24日

Code Review: Two Notification Reliability Issues

I found two issues that can cause stale values or missed notifications under normal edge-case usage.

Both are relatively small fixes, but they can lead to difficult-to-debug behavior because the application may appear to work correctly under normal conditions while silently missing updates during rapid changes or subscriber mutations.


Finding 1 — observeCount() Can Remain Stale After Rapid Writes

Severity: High
Location: subscribeToCount/index.js

Problem

observeCount() currently uses:

javascript
throttleTime(250)

RxJS throttleTime() uses leading-only behavior by default.

This means the first event in a 250 ms window is emitted, while subsequent events during that window are discarded.

For a database count observer, this is problematic because the last database change can be the most important one.

Example

Suppose the current count is 0 and two writes happen very quickly:

javascript
const subscription = query.observeCount().subscribe(console.log);

await database.write(() => tasks.create());
await database.write(() => tasks.create());

If both writes occur within the same 250 ms throttle window, the first change may be emitted while the second change is discarded.

The observer can therefore end up with:

Actual database count: 2
Observer's last emitted count: 1

and remain at 1 until another database change occurs.

In some timing scenarios, the observer can similarly remain at 0 even though the database has already changed.


Why This Happens

Current behavior:

Write #1
   │
   ▼
Emit count ────────────────┐
                           │ 250 ms throttle window
Write #2                   │
   │                       │
   ▼                       │
Discarded ❌               │
                           ▼
                      Window closes

The second write is lost because throttleTime() does not emit the trailing value by default.

For a state-observation API such as observeCount(), losing the final state is undesirable.


️ Suggested Fix

Enable trailing emissions:

javascript
throttleTime(250, undefined, {
  trailing: true
})

This changes the behavior to:

Write #1
   │
   ▼
Emit immediately
   │
   │ 250 ms window
   │
Write #2
   │
   ▼
Remember latest value
   │
   ▼
Emit
…

内容来源: Nozbe/WatermelonDB