Skip to content

Commit

Permalink
Make wait() a method of PromiseInterface
Browse files Browse the repository at this point in the history
  • Loading branch information
trowski committed Aug 7, 2015
1 parent 28892ae commit 325d27e
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 108 deletions.
16 changes: 16 additions & 0 deletions src/Promise/Promise.php
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,22 @@ function (callable $resolve) use ($time) {
}
);
}

/**
* {@inheritdoc}
*/
public function wait()
{
while (null === $this->result) {
if (Loop\isEmpty()) {
throw new UnresolvedError('Loop emptied without resolving promise.');
}

Loop\tick(true);
}

return $this->unwrap()->wait();
}

/**
* {@inheritdoc}
Expand Down
14 changes: 14 additions & 0 deletions src/Promise/PromiseInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ public function isCancelled();
* @throws \Icicle\Promise\Exception\UnresolvedError If the promise has not been resolved.
*/
public function getResult();

/**
* This function may be used to synchronously wait for a promise to be resolved. This function should generally
* not be used within a running event loop, but rather to set up a task (or set of tasks, then use join() or another
* function to group them) and synchronously wait for the task to complete. Using this function in a running event
* loop will not block the loop, but it will prevent control from moving past the call to this function and disrupt
* program flow.
*
* @return mixed Promise fulfillment value.
*
* @throws \Icicle\Promise\Exception\UnresolvedError If the event loop empties without fulfilling the promise.
* @throws \Exception If the promise is rejected, the rejection reason is thrown from this function.
*/
public function wait();

/**
* Iteratively finds the last promise in the pending chain and returns it.
Expand Down
8 changes: 8 additions & 0 deletions src/Promise/Structures/CancelledPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,12 @@ public function getResult()
{
return $this->result->getResult();
}

/**
* {@inheritdoc}
*/
public function wait()
{
return $this->result->wait();
}
}
8 changes: 8 additions & 0 deletions src/Promise/Structures/FulfilledPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,12 @@ public function getResult()
{
return $this->value;
}

/**
* {@inheritdoc}
*/
public function wait()
{
return $this->value;
}
}
8 changes: 8 additions & 0 deletions src/Promise/Structures/LazyPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ public function getResult()
{
return $this->getPromise()->getResult();
}

/**
* {@inheritdoc}
*/
public function wait()
{
return $this->getPromise()->wait();
}

/**
* {@inheritdoc}
Expand Down
8 changes: 8 additions & 0 deletions src/Promise/Structures/RejectedPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,12 @@ public function getResult()
{
return $this->exception;
}

/**
* {@inheritdoc}
*/
public function wait()
{
throw $this->exception;
}
}
33 changes: 0 additions & 33 deletions src/Promise/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,39 +145,6 @@ function lazy(callable $promisor /* ...$args */)
});
}

/**
* This function may be used to synchronously wait for a promise to be resolved. This function should generally
* not be used within a running event loop, but rather to set up a task (or set of tasks, then use join() or another
* function to group them) and synchronously wait for the task to complete. Using this function in a running event
* loop will not block the loop, but it will prevent control from moving past the call to this function and disrupt
* program flow.
*
* @param PromiseInterface $promise
*
* @return mixed Promise fulfillment value.
*
* @throws \Icicle\Promise\Exception\UnresolvedError If the event loop empties without fulfilling the promise.
* @throws \Exception If the promise is rejected, the rejection reason is thrown from this function.
*/
function wait(PromiseInterface $promise)
{
while ($promise->isPending()) {
if (Loop\isEmpty()) {
throw new UnresolvedError('Loop emptied without resolving promise.');
}

Loop\tick(true);
}

$result = $promise->getResult();

if ($promise->isRejected()) {
throw $result;
}

return $result;
}

/**
* Returns a promise that is resolved when all promises are resolved. The returned promise will not reject by itself
* (only if cancelled). Returned promise is fulfilled with an array of resolved promises, with keys identical and
Expand Down
53 changes: 53 additions & 0 deletions tests/Promise/PromiseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2383,4 +2383,57 @@ public function testSplatWithTraversable()

$this->assertTrue($child->isFulfilled());
}

public function testWaitOnFulfilledPromise()
{
$value = 'test';

$this->resolve($value);

$result = $this->promise->wait();

$this->assertSame($value, $result);
}

public function testWaitOnRejectedPromise()
{
$exception = new Exception();

$this->reject($exception);

try {
$result = $this->promise->wait();
$this->fail('Rejection exception should be thrown from wait().');
} catch (Exception $e) {
$this->assertSame($exception, $e);
}
}

/**
* @depends testWaitOnFulfilledPromise
*/
public function testWaitOnPendingPromise()
{
$value = 'test';

$promise = $this->promise->delay(0.1);

$this->resolve($value);

$this->assertTrue($promise->isPending());

$result = $promise->wait();

$this->assertSame($value, $result);
}

/**
* @expectedException \Icicle\Promise\Exception\UnresolvedError
*/
public function testPromiseWithNoResolutionPathThrowsException()
{
$promise = new Promise\Promise(function () {});

$result = $promise->wait();
}
}
75 changes: 0 additions & 75 deletions tests/Promise/PromiseWaitTest.php

This file was deleted.

0 comments on commit 325d27e

Please sign in to comment.