R3 provides deep integration with async/await.
Async Methods
Methods that return a single asynchronous operation (like FirstAsync or LastAsync) return Task<T>. These transform OnErrorResume exceptions into faulted tasks.
Async Operators
You can use async functions within several operators to control execution flow. These operators accept an AwaitOperation to define how concurrent asynchronous tasks are handled.
AwaitOperation Options:
Sequential: All values are queued; the next value waits for the current async method to complete.Drop: New values are dropped if an async operation is currently running.Switch: If a new value arrives while an async operation is running, the current one is cancelled and the new one starts.Parallel: All values are sent to the async method immediately (unlimited concurrency).SequentialParallel: All values are sent immediately, but results are queued and passed to the next operator in order.ThrottleFirstLast: Sends the first and last values while the async method is running.
Key Async Operators:
SelectAwait: Transforms values using an async selector.WhereAwait: Filters values using an async predicate.SubscribeAwait: Subscribes using an async onNext handler.Debounce, ThrottleFirst, ThrottleLast, ThrottleFirstLast: Time-based filtering using async samplers.Chunk: Groups elements into chunks using an async window function.
// Example: Using AwaitOperation.Drop to prevent multiple clicks
button.OnClickAsObservable()
.SelectAwait(async (_, ct) =>
{
var req = await UnityWebRequest.Get("https://google.com/").SendWebRequest().WithCancellation(ct);
return req.downloadHandler.text;
}, AwaitOperation.Drop)
.SubscribeToText(text);
// Example: Using async Chunk to generate chunks at random intervals
Observable.Interval(TimeSpan.FromSeconds(1))
.Index()
.Chunk(async (_, ct) =>
{
await Task.Delay(TimeSpan.FromSeconds(Random.Shared.Next(0, 5)), ct);
})
.Subscribe(xs =>
{
Console.WriteLine(string.Join(", ", xs));
});