Skip to content

Commit 5a7d6eb

Browse files
Add documentation for async computed vars (#1322)
* Add documentation for async computed vars Co-Authored-By: Alek Petuskey <[email protected]> * Fix CI failures by preventing async examples from executing during tests Co-Authored-By: Alek Petuskey <[email protected]> * Fix CI failures by using box parameter for async examples Co-Authored-By: Alek Petuskey <[email protected]> * Fix CI failures by using regular markdown code blocks for async examples Co-Authored-By: Alek Petuskey <[email protected]> * Add interactive demo examples for async computed vars Co-Authored-By: Alek Petuskey <[email protected]> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Alek Petuskey <[email protected]>
1 parent 2f2d988 commit 5a7d6eb

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

docs/vars/computed_vars.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
```python exec
22
import random
33
import time
4+
import asyncio
45

56
import reflex as rx
67
```
@@ -89,3 +90,96 @@ time the state is modified. `last_counter_a_update` is a computed var that only
8990
depends on `counter_a`, so it only gets recomputed when `counter_a` has changes.
9091
Similarly `last_counter_b_update` only depends on `counter_b`, and thus is
9192
updated only when `counter_b` changes.
93+
94+
## Async Computed Vars
95+
96+
Async computed vars allow you to use asynchronous operations in your computed vars.
97+
They are defined as async methods in your State class with the same `@rx.var` decorator.
98+
Async computed vars are useful for operations that require asynchronous processing, such as:
99+
100+
- Fetching data from external APIs
101+
- Database operations
102+
- File I/O operations
103+
- Any other operations that benefit from async/await
104+
105+
```python demo exec
106+
class AsyncVarState(rx.State):
107+
count: int = 0
108+
109+
@rx.var
110+
async def delayed_count(self) -> int:
111+
# Simulate an async operation like an API call
112+
await asyncio.sleep(0.5)
113+
return self.count * 2
114+
115+
@rx.event
116+
def increment(self):
117+
self.count += 1
118+
119+
120+
def async_var_example():
121+
return rx.vstack(
122+
rx.heading("Async Computed Var Example"),
123+
rx.text(f"Count: {AsyncVarState.count}"),
124+
rx.text(f"Delayed count (x2): {AsyncVarState.delayed_count}"),
125+
rx.button("Increment", on_click=AsyncVarState.increment),
126+
spacing="4",
127+
)
128+
```
129+
130+
In this example, `delayed_count` is an async computed var that returns the count multiplied by 2 after a simulated delay.
131+
When the count changes, the async computed var is automatically recomputed.
132+
133+
### Caching Async Computed Vars
134+
135+
Just like regular computed vars, async computed vars can also be cached. This is especially
136+
useful for expensive async operations like API calls or database queries.
137+
138+
```python demo exec
139+
class AsyncCachedVarState(rx.State):
140+
user_id: int = 1
141+
refresh_trigger: int = 0
142+
143+
@rx.var(cache=True)
144+
async def user_data(self) -> dict:
145+
# In a real app, this would be an API call
146+
await asyncio.sleep(1) # Simulate network delay
147+
148+
# Simulate different user data based on user_id
149+
users = {
150+
1: {"name": "Alice", "email": "[email protected]"},
151+
2: {"name": "Bob", "email": "[email protected]"},
152+
3: {"name": "Charlie", "email": "[email protected]"},
153+
}
154+
155+
return users.get(self.user_id, {"name": "Unknown", "email": "unknown"})
156+
157+
@rx.event
158+
def change_user(self):
159+
# Cycle through users 1-3
160+
self.user_id = (self.user_id % 3) + 1
161+
162+
@rx.event
163+
def force_refresh(self):
164+
# This will not affect user_data dependencies, but will trigger a state update
165+
self.refresh_trigger += 1
166+
167+
168+
def async_cached_var_example():
169+
return rx.vstack(
170+
rx.heading("Cached Async Computed Var Example"),
171+
rx.text(f"User ID: {AsyncCachedVarState.user_id}"),
172+
rx.text(f"User Name: {AsyncCachedVarState.user_data['name']}"),
173+
rx.text(f"User Email: {AsyncCachedVarState.user_data['email']}"),
174+
rx.hstack(
175+
rx.button("Change User", on_click=AsyncCachedVarState.change_user),
176+
rx.button("Force Refresh (No Effect)", on_click=AsyncCachedVarState.force_refresh),
177+
),
178+
rx.text("Note: The cached async var only updates when user_id changes, not when refresh_trigger changes."),
179+
spacing="4",
180+
)
181+
```
182+
183+
In this example, `user_data` is a cached async computed var that simulates fetching user data.
184+
It is only recomputed when `user_id` changes, not when other state variables like `refresh_trigger` change.
185+
This demonstrates how caching works with async computed vars to optimize performance for expensive operations.

0 commit comments

Comments
 (0)