Skip to content

Commit 60a4379

Browse files
committed
Some refactoring to prevent infinite loops
1 parent 6e1bb8c commit 60a4379

1 file changed

Lines changed: 55 additions & 27 deletions

File tree

src/React/Promise/Deferred.php

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,55 @@ class Deferred implements PromiseInterface, ResolverInterface
1212

1313
public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
1414
{
15-
if (null !== $this->completed) {
16-
return $this->completed->then($fulfilledHandler, $errorHandler, $progressHandler);
17-
}
18-
1915
$deferred = new static();
2016

21-
if ($progressHandler) {
22-
$progHandler = function ($update) use ($deferred, $progressHandler) {
23-
try {
24-
$deferred->progress(call_user_func($progressHandler, $update));
25-
} catch (\Exception $e) {
26-
$deferred->progress($e);
27-
}
28-
};
17+
if (null !== $this->completed) {
18+
$completed = $this->completed;
19+
20+
$this->executeCallback(function () use ($completed, $fulfilledHandler, $errorHandler, $deferred) {
21+
$completed
22+
->then($fulfilledHandler, $errorHandler)
23+
->then(
24+
function ($value) use ($deferred) {
25+
$deferred->resolve($value);
26+
},
27+
function ($reason) use ($deferred) {
28+
$deferred->reject($reason);
29+
},
30+
function ($update) use ($deferred) {
31+
$deferred->progress($update);
32+
}
33+
);
34+
});
2935
} else {
30-
$progHandler = array($deferred, 'progress');
31-
}
32-
33-
$this->handlers[] = function ($promise) use ($fulfilledHandler, $errorHandler, $deferred, $progHandler) {
34-
$promise
35-
->then($fulfilledHandler, $errorHandler)
36-
->then(
37-
array($deferred, 'resolve'),
38-
array($deferred, 'reject'),
39-
$progHandler
40-
);
41-
};
36+
if ($progressHandler) {
37+
$progHandler = function ($update) use ($deferred, $progressHandler) {
38+
try {
39+
$deferred->progress(call_user_func($progressHandler, $update));
40+
} catch (\Exception $e) {
41+
$deferred->progress($e);
42+
}
43+
};
44+
} else {
45+
$progHandler = array($deferred, 'progress');
46+
}
47+
48+
$this->handlers[] = function ($promise) use ($fulfilledHandler, $errorHandler, $deferred, $progHandler) {
49+
$promise
50+
->then($fulfilledHandler, $errorHandler)
51+
->then(
52+
function ($value) use ($deferred) {
53+
$deferred->resolve($value);
54+
},
55+
function ($reason) use ($deferred) {
56+
$deferred->reject($reason);
57+
},
58+
$progHandler
59+
);
60+
};
4261

43-
$this->progressHandlers[] = $progHandler;
62+
$this->progressHandlers[] = $progHandler;
63+
}
4464

4565
return $deferred->promise();
4666
}
@@ -60,7 +80,7 @@ public function resolve($result = null)
6080

6181
$this->progressHandlers = $this->handlers = array();
6282

63-
return $this->completed;
83+
return $this->promise();
6484
}
6585

6686
public function reject($error = null)
@@ -98,7 +118,15 @@ public function resolver()
98118
protected function processQueue($queue, $value)
99119
{
100120
foreach ($queue as $handler) {
101-
call_user_func($handler, $value);
121+
$this->executeCallback($handler, $value);
102122
}
103123
}
124+
125+
protected function executeCallback($callback/*, $args ... */)
126+
{
127+
$args = func_get_args();
128+
array_shift($args);
129+
130+
call_user_func_array($callback, $args);
131+
}
104132
}

0 commit comments

Comments
 (0)