/** * Create an artificial timeout for any Promise instance * * If the timeout expires prior to promise resolution the returned * promise is failed. * * @param \Amp\Promise $promise The promise to which the timeout applies * @param int $msTimeout The timeout in milliseconds * @return \Amp\Promise */ function timeout(Promise $promise, $msTimeout) { $resolved = false; $promisor = new Deferred(); $watcherId = once(function () use($promisor, &$resolved) { $resolved = true; $promisor->fail(new TimeoutException("Promise resolution timed out")); }, $msTimeout); $promise->when(function ($error = null, $result = null) use($promisor, $watcherId, &$resolved) { if ($resolved) { return; } $resolved = true; cancel($watcherId); if ($error) { $promisor->fail($error); } else { $promisor->succeed($result); } }); return $promisor->promise(); }