<?php
declare(strict_types=1);
use React\EventLoop;
use React\Promise;
* Awaits a promise in blocking manner.
* @param Promise\PromiseInterface $promise
* @param EventLoop\LoopInterface $loop
* @return mixed
*/
function await(Promise\PromiseInterface $promise, EventLoop\LoopInterface $loop)
{
$resolved = $failed = $started = false;
$value = null;
$futureTicks = 0;
$promise->then(
function($argument = null) use(&$resolved, &$value, &$started, $loop): void
{
$resolved = true;
$value = $argument;
$started && $loop->stop();
},
function($error = null) use(&$failed, &$value, &$started, $loop): void
{
$failed = true;
$value = $error;
$started && $loop->stop();
}
);
if (!$resolved && !$failed) {
(function() use(&$resolved, &$failed, &$futureTicks): void {
if (!property_exists($this, 'running')
|| !property_exists($this, 'futureTickQueue')
|| !property_exists($this, 'timers')) {
throw new LogicException(sprintf('%s() does\'t support %s implementation.', __FUNCTION__, get_class($this)));
}
if (!$this->running) {
throw new RuntimeException('Event loop is not running.');
}
(function() use(&$futureTicks): void {
$futureTicks = count($this->queue);
})->call($this->futureTickQueue);
(function() {
foreach ($this->schedule as $id => $scheduled) {
if ($scheduled >= $this->time) {
break;
}
if ($this->timers[$id]->isPeriodic() && isset($this->timers[$id]->timers[$id])) {
$this->schedule[$id] = $this->timers[$id]->getInterval() + $this->time;
$this->sorted = false;
} else {
unset($this->timers[$id], $this->schedule[$id]);
}
break;
}
})->call($this->timers);
})->call($loop);
* Used in promise handler.
* @noinspection PhpUnusedLocalVariableInspection
*/
$started = true;
$loop->run();
(function() use(&$resolved, &$failed, &$futureTicks): void {
$this->running = true;
for ($i = 0; $i < $futureTicks; $i++) {
$this->futureTickQueue->add(function() {});
}
})->call($loop);
}
(function() use($failed, $value): void {
if ($failed && $value instanceof Throwable) {
throw $value;
}
})();
return $value;
}