Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
0.2.0 Preview 1 · Frozen documentation

WhenAny

Waits for one unique input completion without consuming any result.

Sn is under heavy development. Reference extracted from this release’s bundled standard library. Public API examples are not an exhaustive compatibility test. Read the matching release guide for tested workflows and limitations. 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