fromFuture<T> static method
Creates a Cell that emits the result of a Future exactly once.
When to use
Use fromFuture when you have a single asynchronous computation and want its result to participate in the Cell reactive graph. Typical scenarios:
- Loading an initial configuration or user profile
- Waiting for a one-shot network request or database query
- Bridging an existing
asyncAPI into a cell that other cells can derive from or observe
Prefer fromStream when the source produces a continuous sequence of values. Prefer Cell.ingress when the value is generated by an imperative callback rather than a Future.
How it works
- A governed cell is created with a pass-through receptor.
- The supplied
futureis awaited. - When the future completes successfully, its value is wrapped in a Pulse and fed into the cell’s receptor.
- Downstream observers receive that single emission; the cell then remains silent unless invalidated and recreated.
The factory returns a normal Cell; you can freely bind it, observe it,
or compose it with any other factory.
Non‑obvious
- Terminal Bridge: This cell emits at most once. If the resulting
value needs to remain available for late subscribers, you should pipe
this result into a Cell.state or use a Synapses configuration with
PropagationStrategy.persistent. - Error Ingress: If the future completes with an error, the cell
captures the failure. It emits a pulse where the
typeis set to'error'and thepayloadcontains the error object, allowing downstream observers to handle failures reactively. - Signal Neutralization: If this cell is invalidated (via its EphemeralPolicy) before the future completes, the bridge is immediately severed. The eventual result is discarded, and no pulse is emitted to the graph.
- Forensic Provenance: The resulting pulse’s
sourceis automatically set to this bridge instance. This maintains the Chain of Evidence, allowing you to trace the asynchronous origin of a signal during debugging or auditing. - Lifecycle Governance: The cell remains in the reactive graph after its single emission until it is explicitly neutralized or reclaimed by its governing policy.
- Flow Control: While the factory signature is a simple bridge, the underlying implementation respects Synapses configurations for throttling or debouncing if the bridge is part of a complex re-synthesis.
Example
Future<String> loadUserName() async {
await Future.delayed(const Duration(milliseconds: 300));
return 'Alice';
}
final userName = Cell.fromFuture<String>(loadUserName());
Cell.observe(
source: userName,
effect: (Pulse p, {user}) => print('loaded: ${p.payload}'),
);
// after 300 ms → prints "loaded: Alice"
Parameters
future– the Future whose result will be emitted by the cell.
See Also:
- Cell.fromStream: For continuous asynchronous data sources.
- Cell.ingress: For manual, callback-driven data entry.
- Example: See
example/async_bridge_demo.dartfor a walkthrough of bridging legacy async APIs into forensic pipelines.
Implementation
static Cell fromFuture<T>(
Future<T> future) =>
_fromFuture<T>(future);