TaskSet::joinNext
(PHP 8.6+, True Async 1.0)
php
public TaskSet::joinNext(): Async\FutureReturns a Future that resolves with the result of the first completed task — whether successful or failed. If the task finished with an error, the Future rejects with that exception.
After delivering the result, the entry is automatically removed from the set, and count() decreases by 1.
Remaining tasks continue running.
If a completed task already exists, the Future resolves immediately.
The returned Future supports a cancellation token via await(?Completable $cancellation).
Return Value
Async\Future — a future result of the first completed task. Call ->await() to get the value.
Errors
- Throws
Async\AsyncExceptionif the set is empty. - The
Futurerejects with the task's exception if the first completed task failed with an error.
Examples
Example #1 Sequential result processing
php
<?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
});Example #2 Processing loop
php
<?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()}");
}
}
});Example #3 With timeout
php
<?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";
}
});See Also
- TaskSet::joinAny — First successful result
- TaskSet::joinAll — All results
- TaskGroup::race — Equivalent without auto-cleanup