Skip to content

Commit 3ba6144

Browse files
committed
Implement cancellation for lazy promises
1 parent a469321 commit 3ba6144

3 files changed

Lines changed: 48 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ a promise has no effect.
508508

509509
* [FulfilledPromise](#fulfilledpromise)
510510
* [RejectedPromise](#rejectedpromise)
511+
* [LazyPromise](#lazypromise)
511512

512513
Examples
513514
--------

src/React/Promise/LazyPromise.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace React\Promise;
44

5-
class LazyPromise implements PromiseInterface
5+
class LazyPromise implements PromiseInterface, CancellablePromiseInterface
66
{
77
private $factory;
88
private $promise;
@@ -13,6 +13,19 @@ public function __construct($factory)
1313
}
1414

1515
public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
16+
{
17+
return $this->promise()->then($fulfilledHandler, $errorHandler, $progressHandler);
18+
}
19+
20+
public function cancel()
21+
{
22+
$promise = $this->promise();
23+
if ($promise instanceof CancellablePromiseInterface) {
24+
$promise->cancel();
25+
}
26+
}
27+
28+
private function promise()
1629
{
1730
if (null === $this->promise) {
1831
try {
@@ -21,7 +34,6 @@ public function then($fulfilledHandler = null, $errorHandler = null, $progressHa
2134
$this->promise = new RejectedPromise($exception);
2235
}
2336
}
24-
25-
return $this->promise->then($fulfilledHandler, $errorHandler, $progressHandler);
37+
return $this->promise;
2638
}
2739
}

tests/React/Promise/LazyPromiseTest.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ public function shouldReturnPromiseIfFactoryReturnsNull()
6363
$p = new LazyPromise($factory);
6464
$this->assertInstanceOf('React\\Promise\\PromiseInterface', $p->then());
6565
}
66-
66+
6767
/** @test */
6868
public function shouldReturnRejectedPromiseIfFactoryThrowsException()
6969
{
7070
$exception = new \Exception();
71-
71+
7272
$factory = $this->createCallableMock();
7373
$factory
7474
->expects($this->once())
@@ -85,4 +85,34 @@ public function shouldReturnRejectedPromiseIfFactoryThrowsException()
8585

8686
$p->then($this->expectCallableNever(), $errorHandler);
8787
}
88+
89+
/** @test */
90+
public function shouldInvokeCancellationHandlerAndStayPendingWhenCallingCancel()
91+
{
92+
$once = $this->expectCallableOnce();
93+
94+
$factory = function () use ($once){
95+
return new Deferred($once);
96+
};
97+
98+
$p = new LazyPromise($factory);
99+
$p->cancel();
100+
101+
$p->then($this->expectCallableNever(), $this->expectCallableNever());
102+
}
103+
104+
/** @test */
105+
public function shouldNotInvokeCancellationHandlerIfPromiseIsNotCancellable()
106+
{
107+
$mock = $this->getMock('React\\Promise\\PromiseInterface');
108+
109+
$factory = function () use ($mock){
110+
return $mock;
111+
};
112+
113+
$p = new LazyPromise($factory);
114+
$p->cancel();
115+
116+
$p->then($this->expectCallableNever(), $this->expectCallableNever());
117+
}
88118
}

0 commit comments

Comments
 (0)