Skip to content

Commit 226d704

Browse files
committed
Add lazy promise
1 parent 8573049 commit 226d704

3 files changed

Lines changed: 98 additions & 0 deletions

File tree

src/React/Promise/LazyPromise.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace React\Promise;
4+
5+
class LazyPromise implements PromiseInterface
6+
{
7+
private $factory;
8+
private $promise;
9+
10+
public function __construct($factory)
11+
{
12+
$this->factory = $factory;
13+
}
14+
15+
public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
16+
{
17+
if (null === $this->promise) {
18+
try {
19+
$this->promise = Util::promiseFor(call_user_func($this->factory));
20+
} catch (\Exception $exception) {
21+
$this->promise = new RejectedPromise($exception);
22+
}
23+
}
24+
25+
return $this->promise->then($fulfilledHandler, $errorHandler, $progressHandler);
26+
}
27+
}

src/React/Promise/When.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public static function reject($promiseOrValue = null)
1414
return Util::rejectedPromiseFor($promiseOrValue);
1515
}
1616

17+
public static function lazy($factory)
18+
{
19+
return new LazyPromise($factory);
20+
}
21+
1722
public static function all($promisesOrValues, $fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
1823
{
1924
$promise = static::map($promisesOrValues, function ($val) {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
namespace React\Promise;
4+
5+
/**
6+
* @group Promise
7+
* @group LazyPromise
8+
*/
9+
class LazyPromiseTest extends TestCase
10+
{
11+
/** @test */
12+
public function shouldNotCallFactoryIfThenIsNotInvoked()
13+
{
14+
$factory = $this->createCallableMock();
15+
$factory
16+
->expects($this->never())
17+
->method('__invoke');
18+
19+
new LazyPromise($factory);
20+
}
21+
22+
/** @test */
23+
public function shouldCallFactoryIfThenIsInvoked()
24+
{
25+
$factory = $this->createCallableMock();
26+
$factory
27+
->expects($this->once())
28+
->method('__invoke');
29+
30+
$p = new LazyPromise($factory);
31+
$p->then();
32+
}
33+
34+
/** @test */
35+
public function shouldReturnPromiseFromFactory()
36+
{
37+
$factory = $this->createCallableMock();
38+
$factory
39+
->expects($this->once())
40+
->method('__invoke')
41+
->will($this->returnValue(new FulfilledPromise(1)));
42+
43+
$fulfilledHandler = $this->createCallableMock();
44+
$fulfilledHandler
45+
->expects($this->once())
46+
->method('__invoke')
47+
->with($this->identicalTo(1));
48+
49+
$p = new LazyPromise($factory);
50+
51+
$p->then($fulfilledHandler);
52+
}
53+
54+
/** @test */
55+
public function shouldReturnPromiseIfFactoryReturnsNull()
56+
{
57+
$factory = $this->createCallableMock();
58+
$factory
59+
->expects($this->once())
60+
->method('__invoke')
61+
->will($this->returnValue(null));
62+
63+
$p = new LazyPromise($factory);
64+
$this->assertInstanceOf('React\\Promise\\PromiseInterface', $p->then());
65+
}
66+
}

0 commit comments

Comments
 (0)