Skip to content

Commit 28b5600

Browse files
committed
Fix circular references when resolving with a promise which follows itself
1 parent 3524ed7 commit 28b5600

1 file changed

Lines changed: 24 additions & 15 deletions

File tree

src/Promise.php

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function __construct(callable $resolver, callable $canceller = null)
2222
public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
2323
{
2424
if (null !== $this->result) {
25-
return $this->result()->then($onFulfilled, $onRejected, $onProgress);
25+
return $this->result->then($onFulfilled, $onRejected, $onProgress);
2626
}
2727

2828
if (null === $this->canceller) {
@@ -43,7 +43,7 @@ public function then(callable $onFulfilled = null, callable $onRejected = null,
4343
public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
4444
{
4545
if (null !== $this->result) {
46-
return $this->result()->done($onFulfilled, $onRejected, $onProgress);
46+
return $this->result->done($onFulfilled, $onRejected, $onProgress);
4747
}
4848

4949
$this->handlers[] = function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected) {
@@ -155,15 +155,7 @@ private function notify($update = null)
155155

156156
private function settle(ExtendedPromiseInterface $promise)
157157
{
158-
if ($promise instanceof LazyPromise) {
159-
$promise = $promise->promise();
160-
}
161-
162-
if ($promise === $this) {
163-
$promise = new RejectedPromise(
164-
new \LogicException('Cannot resolve a promise with itself.')
165-
);
166-
}
158+
$promise = $this->unwrap($promise);
167159

168160
$handlers = $this->handlers;
169161

@@ -175,13 +167,30 @@ private function settle(ExtendedPromiseInterface $promise)
175167
}
176168
}
177169

178-
private function result()
170+
private function unwrap($promise)
179171
{
180-
while ($this->result instanceof self && null !== $this->result->result) {
181-
$this->result = $this->result->result;
172+
$promise = $this->extract($promise);
173+
174+
while ($promise instanceof self && null !== $promise->result) {
175+
$promise = $this->extract($promise->result);
176+
}
177+
178+
return $promise;
179+
}
180+
181+
private function extract($promise)
182+
{
183+
if ($promise instanceof LazyPromise) {
184+
$promise = $promise->promise();
185+
}
186+
187+
if ($promise === $this) {
188+
return new RejectedPromise(
189+
new \LogicException('Cannot resolve a promise with itself.')
190+
);
182191
}
183192

184-
return $this->result;
193+
return $promise;
185194
}
186195

187196
private function call(callable $callback)

0 commit comments

Comments
 (0)