From 170bb53f61a91e73dc1ee58ce53096c050eeb651 Mon Sep 17 00:00:00 2001 From: Jan Sorgalla Date: Fri, 3 Jul 2015 10:11:20 +0200 Subject: [PATCH] Assign result and reset handlers early when settling a promise This fixes issues when resolving a promise in its own fulfillment or rejection handlers. Thanks @clue for spotting it. --- src/Promise.php | 11 +++++------ tests/PromiseTest/RejectTestTrait.php | 5 +++++ tests/PromiseTest/ResolveTestTrait.php | 5 +++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Promise.php b/src/Promise.php index 0ef8ed9e..75379eaf 100644 --- a/src/Promise.php +++ b/src/Promise.php @@ -150,15 +150,14 @@ private function notify($update = null) private function settle(ExtendedPromiseInterface $promise) { - $result = $promise; - - foreach ($this->handlers as $handler) { - $handler($result); - } + $handlers = $this->handlers; $this->progressHandlers = $this->handlers = []; + $this->result = $promise; - $this->result = $result; + foreach ($handlers as $handler) { + $handler($promise); + } } private function result() diff --git a/tests/PromiseTest/RejectTestTrait.php b/tests/PromiseTest/RejectTestTrait.php index 7d6f65fd..063f178a 100644 --- a/tests/PromiseTest/RejectTestTrait.php +++ b/tests/PromiseTest/RejectTestTrait.php @@ -98,6 +98,11 @@ public function rejectShouldMakePromiseImmutable() ->with($this->identicalTo(1)); $adapter->promise() + ->then(null, function ($value) use ($adapter) { + $adapter->reject(3); + + return Promise\reject($value); + }) ->then( $this->expectCallableNever(), $mock diff --git a/tests/PromiseTest/ResolveTestTrait.php b/tests/PromiseTest/ResolveTestTrait.php index b05f7fe8..46f95ad4 100644 --- a/tests/PromiseTest/ResolveTestTrait.php +++ b/tests/PromiseTest/ResolveTestTrait.php @@ -98,6 +98,11 @@ public function resolveShouldMakePromiseImmutable() ->with($this->identicalTo(1)); $adapter->promise() + ->then(function ($value) use ($adapter) { + $adapter->resolve(3); + + return $value; + }) ->then( $mock, $this->expectCallableNever()