Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Development · Evolving reference

WhenAny

Waits for one unique input completion without consuming any result.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. Read the status →

Module std.task

import std.task;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

WhenAnyAsync

pub async fn WhenAnyAsync<T>(Tasks: readonly Task<T>[], Token: CancellationToken)
    -> Task<Result<usize, WhenAnyError>>

Waits for one unique input completion without consuming any result. T: Exact input completion type, including void. Tasks: Borrowed stable readonly handle sequence; keep all input owners live through completion. Token: Owned wait-only cancellation observation, inert by default. Return: Lowest already-ready index, one later elected index, or ordinary wait error. Warning: Neither winner nor losers are cancelled, moved or destroyed by this operation. The caller still joins remaining work and consumes/observes results normally. Pending registration may allocate or start a captured executor lazily; it never polls, blocks a worker on an input, or starts a dedicated wait thread.

Example

module example.unique_when_any;
from std.task import Task, SharedTask, Share, WhenAnyAsync, WhenAllAsync;
from std.collections import Vector;
async fn AnswerAsync(Value: i32) -> Task<i32> { return Value; }
async fn Main() -> Task<i32> {
    var Tasks = Vector<Task<i32>>();
    if Tasks.TryPush(AnswerAsync(20)) is .Err { Error = _ } { return 1; }
    if Tasks.TryPush(AnswerAsync(22)) is .Err { Error = _ } { return 2; }
    let Winner = switch await WhenAnyAsync<i32>(Tasks.AsSlice()) {
        case .Ok { Value = Index } => break Index;
        case .Err => return 3;
    };
    if Winner != 0 { return 4; } // Both eager tasks were already complete.
    var Values = {
        // Keep writable result storage through the explicit noncopy payload transfer.
        var ValuesCreation = await WhenAllAsync<i32>(move(Tasks));
        switch ValuesCreation {
            case .Ok { Value = CompletedValues: mut Vector<i32>& } => break move(CompletedValues);
            case .Err => return 5;
        }
    };
    if Values.At(0) != 20 || Values.At(1) != 22 { return 6; }
    return 0;
}

WhenAnyAsync

pub fn WhenAnyAsync<T>(Tasks: readonly Task<T>[])
    -> Task<Result<usize, WhenAnyError>>

Supplies the omitted arguments to WhenAnyAsync. Note: Defaults: Token = CancellationToken(). T: Same generic argument and constraints as the full operation. Tasks: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library