Skip to content

Async Operations

Ahmad Al-freihat edited this page Jan 1, 2026 · 1 revision

Async Operations

All functional operations have async equivalents for asynchronous scenarios.

MapAsync

Transform elements asynchronously:

NonEmptyList<int> numbers = new(1, 2, 3);

NonEmptyList<string> results = await numbers.MapAsync(async x =>
{
    await Task.Delay(100);
    return x.ToString();
});
// Result: ["1", "2", "3"]

MapParallelAsync

Execute transformations in parallel:

NonEmptyList<int> numbers = new(1, 2, 3);

NonEmptyList<int> parallelResults = await numbers.MapParallelAsync(async x =>
{
    await Task.Delay(100);
    return x * 2;
});
// Result: [2, 4, 6] - processed in parallel

With Degree of Parallelism

Limit concurrent operations:

NonEmptyList<int> numbers = new(1, 2, 3, 4, 5, 6, 7, 8);

NonEmptyList<int> throttled = await numbers.MapParallelAsync(
    async x =>
    {
        await Task.Delay(100);
        return x * 2;
    },
    maxDegreeOfParallelism: 2
);
// Maximum 2 concurrent operations

FilterAsync

Filter elements asynchronously:

NonEmptyList<int> numbers = new(1, 2, 3, 4, 5);

NonEmptyList<int>? evenNumbers = await numbers.FilterAsync(async x =>
{
    await Task.Delay(10);
    return x % 2 == 0;
});
// Result: [2, 4] or null if all filtered out

FoldAsync

Aggregate elements asynchronously:

NonEmptyList<int> numbers = new(1, 2, 3, 4);

int sum = await numbers.FoldAsync(0, async (acc, x) =>
{
    await Task.Delay(10);
    return acc + x;
});
// Result: 10

AllAsync and AnyAsync

Check conditions asynchronously:

NonEmptyList<int> numbers = new(1, 2, 3, 4, 5);

// Check if all elements satisfy a condition
bool allPositive = await numbers.AllAsync(async x =>
{
    await Task.Delay(1);
    return x > 0;
});
// Result: true

// Check if any element satisfies a condition
bool hasEven = await numbers.AnyAsync(async x =>
{
    await Task.Delay(1);
    return x % 2 == 0;
});
// Result: true

FirstOrDefaultAsync

Find first matching element asynchronously:

NonEmptyList<int> numbers = new(1, 2, 3, 4, 5);

int? firstEven = await numbers.FirstOrDefaultAsync(async x =>
{
    await Task.Delay(10);
    return x % 2 == 0;
});
// Result: 2

ToAsyncEnumerable

Convert to IAsyncEnumerable for async iteration:

NonEmptyList<int> numbers = new(1, 2, 3);

await foreach (int item in numbers.ToAsyncEnumerable())
{
    Console.WriteLine(item);
    await Task.Delay(100);
}
// Output: 1, 2, 3 (with delays)

Practical Examples

API Calls

NonEmptyList<int> userIds = new(1, 2, 3);

NonEmptyList<User> users = await userIds.MapParallelAsync(
    async id => await httpClient.GetFromJsonAsync<User>($"/api/users/{id}"),
    maxDegreeOfParallelism: 5
);

Database Operations

NonEmptyList<Order> orders = GetOrders();

bool allValid = await orders.AllAsync(async order =>
    await orderValidator.ValidateAsync(order)
);

Batch Processing

NonEmptyList<Document> documents = GetDocuments();

await documents.ForEachAsync(async doc =>
{
    await ProcessDocumentAsync(doc);
    await SaveResultAsync(doc);
});

Next Steps

Clone this wiki locally