TaskSet::joinNext

(PHP 8.6+, True Async 1.0)

public TaskSet::joinNext(): Async\Future

Devuelve un Future que se resuelve con el resultado de la primera tarea completada, ya sea exitosa o fallida. Si la tarea terminó con error, el Future se rechaza con esa excepción.

Tras la entrega del resultado, la entrada se elimina automáticamente del conjunto, y count() disminuye en 1.

Las tareas restantes continúan ejecutándose.

Si ya existe una tarea completada, el Future se resuelve inmediatamente.

El Future devuelto admite un token de cancelación mediante await(?Completable $cancellation).

Valor de retorno

Async\Future — un resultado futuro de la primera tarea completada. Llama a ->await() para obtener el valor.

Errores

Ejemplos

Ejemplo #1 Procesamiento secuencial de resultados

<?php

use Async\TaskSet;

spawn(function() {
    $set = new TaskSet();

    $set->spawn(fn() => fetchUser(1));
    $set->spawn(fn() => fetchUser(2));
    $set->spawn(fn() => fetchUser(3));

    echo "before: count=" . $set->count() . "\n"; // 3

    $first = $set->joinNext()->await();
    echo "after first: count=" . $set->count() . "\n"; // 2

    $second = $set->joinNext()->await();
    echo "after second: count=" . $set->count() . "\n"; // 1
});

Ejemplo #2 Bucle de procesamiento

<?php

use Async\TaskSet;

spawn(function() {
    $set = new TaskSet(concurrency: 5);

    foreach ($urls as $url) {
        $set->spawn(fn() => httpClient()->get($url)->getBody());
    }
    $set->seal();

    while ($set->count() > 0) {
        try {
            $body = $set->joinNext()->await();
            processResponse($body);
        } catch (\Throwable $e) {
            log("Error: {$e->getMessage()}");
        }
    }
});

Ejemplo #3 Con timeout

<?php

use Async\TaskSet;

spawn(function() {
    $set = new TaskSet();

    $set->spawn(fn() => slowApi()->fetchReport());
    $set->spawn(fn() => anotherApi()->fetchStats());

    try {
        $result = $set->joinNext()->await(Async\timeout(5.0));
    } catch (Async\TimeoutException) {
        echo "No task completed within 5 seconds\n";
    }
});

Ver también