TaskGroup::any

(PHP 8.6+, True Async 1.0)

public TaskGroup::any(): Async\Future

Возвращает Future, который разрешится результатом первой успешно завершившейся задачи. Задачи, завершившиеся с ошибкой, пропускаются. Остальные задачи продолжают работать.

Если все задачи завершились с ошибкой — Future реджектится с CompositeException.

Возвращённый Future поддерживает токен отмены через await(?Completable $cancellation).

Возвращаемое значение

Async\Future — будущий результат первой успешной задачи. Для получения значения вызовите ->await().

Ошибки

Примеры

Пример #1 Первый успешный

<?php

use Async\TaskGroup;

spawn(function() {
    $group = new TaskGroup();

    $group->spawn(fn() => throw new \RuntimeException("fail 1"));
    $group->spawn(fn() => throw new \RuntimeException("fail 2"));
    $group->spawn(fn() => "success!");

    $result = $group->any()->await();
    echo $result . "\n"; // "success!"

    // Ошибки упавших задач нужно явно подавить
    $group->suppressErrors();
});

Пример #2 Все упали

<?php

use Async\TaskGroup;

spawn(function() {
    $group = new TaskGroup();

    $group->spawn(fn() => throw new \RuntimeException("err 1"));
    $group->spawn(fn() => throw new \RuntimeException("err 2"));

    $group->seal();

    try {
        $group->any()->await();
    } catch (\Async\CompositeException $e) {
        echo count($e->getExceptions()) . " ошибок\n"; // "2 ошибок"
    }
});

Пример #3 Устойчивый поиск с таймаутом

<?php

use Async\TaskGroup;

spawn(function() {
    $group = new TaskGroup();

    $group->spawn(fn() => searchGoogle($query));
    $group->spawn(fn() => searchBing($query));
    $group->spawn(fn() => searchDuckDuckGo($query));

    $timeout = Async\timeout(3.0);

    try {
        $result = $group->any()->await($timeout);
    } catch (Async\TimeoutException) {
        echo "Ни один провайдер не ответил за 3 секунды\n";
    }

    $group->suppressErrors();
});

См. также