Running generators concurrently
In addition to calling multiple generators sequentially,
you can also use Await::all()
or Await::race()
to run multiple generators.
If you have a JavaScript background, you can think of Generator
objects as promises
and Await::all()
and Await::race()
are just Promise.all()
and Promise.race()
.
Await::all()
Await::all()
allows you to run an array of generators at the same time.
If you yield Await::all($array)
, your function resumes when
all generators in $array
have finished executing.
function loadData(string $name): Generator {
// some async logic
return strlen($name);
}
$array = [
"SOFe" => $this->loadData("SOFe"), // don't yield it yet!
"PEMapModder" => $this->loadData("PEMapModder"),
];
$results = yield from Await::all($array);
var_dump($result);
Output:
array(2) {
["SOFe"]=>
int(4)
["PEMapModder"]=>
int(11)
}
Yielding Await::all()
will throw an exception
as long as any of the generators throw.
The error condition will not wait until all generators return.
Await::race()
Await::race()
is like Await::all()
,
but it resumes as long as any of the generators return or throw.
The returned value of yield from
is a 2-element array containing the key and the value.
function sleep(int $time): Generator {
// Let's say this is an await version of `scheduleDelayedTask`
return $time;
}
function main(): Generator {
[$k, $v] = yield from Await::race([
"two" => $this->sleep(2),
"one" => $this->sleep(1),
]);
var_dump($k); // string(3) "one"
var_dump($v); // int(1)
}