public function __construct(Promise $promise) { $this->valids[$this->readPos] = new Deferred(); $promise->watch(function ($data) { $curPos = $this->writePos; $this->writePos++; $this->valids[] = new Deferred(); $this->values[$curPos] = $data; $this->valids[$curPos]->succeed(true); }); $promise->when(function ($error, $result) { if ($error) { $this->valids[$this->writePos]->fail($error); } else { $curPos = $this->writePos; $this->values[$this->writePos++] = $result; $this->valids[$curPos]->succeed(false); } }); }
/** * Block script execution indefinitely until the specified Promise resolves * * In the event of promise failure this method will throw the exception responsible for the failure. * Otherwise the promise's resolved value is returned. * * @param \Amp\Promise $promise The promise on which to wait * @throws \Exception if the promise fails * @return mixed Returns the eventual resolution result for the specified promise */ function wait(Promise $promise) { $isWaiting = true; $resolvedError = null; $resolvedResult = null; $promise->when(function ($error, $result) use(&$isWaiting, &$resolvedError, &$resolvedResult) { $isWaiting = false; $resolvedError = $error; $resolvedResult = $result; }); while ($isWaiting) { tick(); } if ($resolvedError) { throw $resolvedError; } return $resolvedResult; }
/** * Create an artificial timeout for any Promise. * * If the timeout expires before the promise is resolved, the returned promise fails with an instance of * \Amp\TimeoutException. * * @param \Interop\Async\Promise $promise * @param int $timeout Timeout in milliseconds. * * @return \Interop\Async\Promise */ function timeout(Promise $promise, int $timeout) : Promise { $deferred = new Deferred(); $resolved = false; $watcher = Loop::delay($timeout, function () use(&$resolved, $deferred) { if (!$resolved) { $resolved = true; $deferred->fail(new TimeoutException()); } }); $promise->when(function () use(&$resolved, $promise, $deferred, $watcher) { Loop::cancel($watcher); if ($resolved) { return; } $resolved = true; $deferred->resolve($promise); }); return $deferred->promise(); }