-
-
Notifications
You must be signed in to change notification settings - Fork 0
Awaiting Results
await() runs a single task to completion and gives you its return value. It
is the bridge between "fire a task and forget it" (defer()) and "I need this
result before I continue." All examples assume:
require_once 'vendor/autoload.php';
use InitPHP\FiberLoops\Loop;public function await(callable|Fiber $task): mixedHow await() behaves depends on where you call it from.
Called from the main script (not inside a fiber), await() drives the task to
completion synchronously and returns its value. The task may yield with next()
as often as it likes:
$loop = new Loop();
$user = $loop->await(function () use ($loop) {
$loop->next(); // pretend this is I/O
$loop->next();
return ['id' => 42, 'name' => 'Ada'];
});
echo "user: {$user['id']} / {$user['name']}\n";user: 42 / Ada
This works no matter how many times the task yields — there is no special case for "awaiting from outside the loop."
This is where await() earns its keep. Called from inside a running task, it
yields to the scheduler between the awaited task's steps, so the loop's other
tasks keep running while you wait for the result.
$loop = new Loop();
$loop->defer(function () use ($loop) {
echo "worker: awaiting a sub-task\n";
$sum = $loop->await(function () use ($loop) {
$total = 0;
foreach (range(1, 3) as $n) {
$total += $n;
$loop->next();
}
return $total;
});
echo "worker: sub-task returned $sum\n";
});
$loop->defer(function () use ($loop) {
foreach (['tick', 'tick', 'tick'] as $t) {
echo "heartbeat: $t\n";
$loop->next();
}
});
$loop->run();worker: awaiting a sub-task
heartbeat: tick
heartbeat: tick
heartbeat: tick
worker: sub-task returned 6
The heartbeat task runs throughout — one tick per step of the awaited sub-task —
instead of being frozen until await() returns.
await() returns whatever the task returns, or null if it returns nothing:
$loop = new Loop();
$value = $loop->await(fn () => 'a result');
$nothing = $loop->await(function () { /* no return */ });
var_dump($value, $nothing);string(8) "a result"
NULL
await() accepts a Fiber, whether or not it has already been started. This is
handy when another part of your code created the fiber:
$fiber = new Fiber(function () {
Fiber::suspend();
Fiber::suspend();
return 99;
});
$fiber->start(); // already started elsewhere
$loop = new Loop();
echo $loop->await($fiber) . "\n";99
An unstarted fiber is started for you; an already-terminated fiber simply yields its return value.
await() calls nest naturally — a task you await can itself await another:
$loop = new Loop();
$result = $loop->await(function () use ($loop) {
$inner = $loop->await(function () use ($loop) {
$loop->next();
return 20;
});
return $inner + 1;
});
echo $result . "\n";21
await() runs a single task to completion before returning. If you want several
tasks running concurrently and then collect their results, do not chain await()
calls — defer() the tasks instead and let them write their results into a shared
place. See
Recipes → Collecting results from concurrent tasks.
-
Do not
await()the currently running fiber (for example a task's own fiber). Resuming the running fiber is invalid and PHP raises aFiberError. -
await()is wait-for-result, not fire-and-forget. For fire-and-forget, usedefer(). - An exception thrown inside the awaited task propagates out of
await()— see Error Handling.
- Deferring & Running Tasks — fire-and-forget tasks.
- Recipes — concurrent result collection, pipelines and more.
- API Reference — the exact contract.
Getting Started
Using FiberLoops
Guides
Reference