Observable: Practical Controls
batch()
Use batch() to group related updates and avoid redundant recalculations.
This is especially useful when multiple source observables affect the same derived value.
from nuiitivet.observable import Observable, batch
price = Observable(100)
quantity = Observable(2)
total = price.combine(quantity).compute(lambda p, q: p * q)
with batch():
price.value = 200
quantity.value = 3
Inside UI event handlers, batching is commonly applied automatically.
debounce()
Use debounce() when you want to run logic only after input has settled for a period of time.
from nuiitivet.observable import Observable
query = Observable("")
debounced_query = query.debounce(0.5)
debounced_query.subscribe(lambda q: print(f"search: {q}"))
Typical use cases are search boxes, validation, and autosave.
throttle()
Use throttle() when you need periodic sampling for high-frequency updates.
mouse_x = Observable(0)
throttled_x = mouse_x.throttle(0.1)
throttled_x.subscribe(lambda x: print(f"x={x}"))
Typical use cases are scrolling, pointer movement, resize handling, and real-time streams.
debounce vs throttle
| Feature | debounce | throttle |
|---|---|---|
| First change | Wait | Execute immediately |
| Continuous changes | Keep waiting | Execute periodically |
| Last change | Always execute | Depends on timing |
| Execution count | Minimized | Regular |
Chaining
formatted_query = (
query
.debounce(0.5)
.map(lambda q: q.strip().lower())
.dispatch_to_ui()
)
position_display = (
mouse_x
.throttle(0.1)
.combine(mouse_y.throttle(0.1))
.compute(lambda x, y: f"({x}, {y})")
)