Skip to content

Commit 587a098

Browse files
clueWyriHaximus
authored andcommitted
Use static internal callbacks without binding to parent promise
1 parent afb3276 commit 587a098

2 files changed

Lines changed: 71 additions & 5 deletions

File tree

src/Promise.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ public function done(callable $onFulfilled = null, callable $onRejected = null):
6262
return;
6363
}
6464

65-
$this->handlers[] = function (PromiseInterface $promise) use ($onFulfilled, $onRejected) {
65+
$this->handlers[] = static function (PromiseInterface $promise) use ($onFulfilled, $onRejected) {
6666
$promise
6767
->done($onFulfilled, $onRejected);
6868
};
6969
}
7070

7171
public function otherwise(callable $onRejected): PromiseInterface
7272
{
73-
return $this->then(null, function ($reason) use ($onRejected) {
73+
return $this->then(null, static function ($reason) use ($onRejected) {
7474
if (!_checkTypehint($onRejected, $reason)) {
7575
return new RejectedPromise($reason);
7676
}
@@ -81,11 +81,11 @@ public function otherwise(callable $onRejected): PromiseInterface
8181

8282
public function always(callable $onFulfilledOrRejected): PromiseInterface
8383
{
84-
return $this->then(function ($value) use ($onFulfilledOrRejected) {
84+
return $this->then(static function ($value) use ($onFulfilledOrRejected) {
8585
return resolve($onFulfilledOrRejected())->then(function () use ($value) {
8686
return $value;
8787
});
88-
}, function ($reason) use ($onFulfilledOrRejected) {
88+
}, static function ($reason) use ($onFulfilledOrRejected) {
8989
return resolve($onFulfilledOrRejected())->then(function () use ($reason) {
9090
return new RejectedPromise($reason);
9191
});
@@ -130,7 +130,7 @@ public function cancel(): void
130130
private function resolver(callable $onFulfilled = null, callable $onRejected = null): callable
131131
{
132132
return function ($resolve, $reject) use ($onFulfilled, $onRejected) {
133-
$this->handlers[] = function (PromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject) {
133+
$this->handlers[] = static function (PromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject) {
134134
$promise
135135
->then($onFulfilled, $onRejected)
136136
->done($resolve, $reject);

tests/PromiseTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,72 @@ public function shouldIgnoreNotifyAfterReject()
190190
$promise->cancel();
191191
}
192192

193+
194+
/** @test */
195+
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromise()
196+
{
197+
gc_collect_cycles();
198+
$promise = new Promise(function () { });
199+
unset($promise);
200+
201+
$this->assertSame(0, gc_collect_cycles());
202+
}
203+
204+
/** @test */
205+
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithThenFollowers()
206+
{
207+
gc_collect_cycles();
208+
$promise = new Promise(function () { });
209+
$promise->then()->then()->then();
210+
unset($promise);
211+
212+
$this->assertSame(0, gc_collect_cycles());
213+
}
214+
215+
/** @test */
216+
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithDoneFollowers()
217+
{
218+
gc_collect_cycles();
219+
$promise = new Promise(function () { });
220+
$promise->done();
221+
unset($promise);
222+
223+
$this->assertSame(0, gc_collect_cycles());
224+
}
225+
226+
/** @test */
227+
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithOtherwiseFollowers()
228+
{
229+
gc_collect_cycles();
230+
$promise = new Promise(function () { });
231+
$promise->otherwise(function () { });
232+
unset($promise);
233+
234+
$this->assertSame(0, gc_collect_cycles());
235+
}
236+
237+
/** @test */
238+
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithAlwaysFollowers()
239+
{
240+
gc_collect_cycles();
241+
$promise = new Promise(function () { });
242+
$promise->always(function () { });
243+
unset($promise);
244+
245+
$this->assertSame(0, gc_collect_cycles());
246+
}
247+
248+
/** @test */
249+
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithProgressFollowers()
250+
{
251+
gc_collect_cycles();
252+
$promise = new Promise(function () { });
253+
$promise->then(null, null, function () { });
254+
unset($promise);
255+
256+
$this->assertSame(0, gc_collect_cycles());
257+
}
258+
193259
/** @test */
194260
public function shouldFulfillIfFullfilledWithSimplePromise()
195261
{

0 commit comments

Comments
 (0)