@@ -15,14 +15,15 @@ class Promise implements PromiseInterface {
15
15
private array $ chain ;
16
16
/** @var CatchChain[] */
17
17
private array $ uncalledCatchChain ;
18
+ /** @var Throwable[] */
19
+ private array $ handledRejections ;
18
20
/** @var callable */
19
21
private $ executor ;
20
- private bool $ completed ;
21
22
22
23
public function __construct (callable $ executor ) {
23
- $ this ->completed = false ;
24
24
$ this ->chain = [];
25
25
$ this ->uncalledCatchChain = [];
26
+ $ this ->handledRejections = [];
26
27
27
28
$ this ->executor = $ executor ;
28
29
$ this ->callExecutor ();
@@ -123,7 +124,8 @@ private function reset():void {
123
124
}
124
125
125
126
private function tryComplete ():void {
126
- if (empty ($ this ->chain ) && $ this ->getState () === PromiseState::PENDING ) {
127
+ if (empty ($ this ->chain )) {
128
+ $ this ->throwUnhandledRejection ();
127
129
return ;
128
130
}
129
131
if ($ this ->getState () !== PromiseState::PENDING ) {
@@ -145,10 +147,7 @@ function(Chainable $a, Chainable $b) {
145
147
return 0 ;
146
148
}
147
149
);
148
- $ handledRejections = [];
149
150
150
- $ emptyChain = empty ($ this ->chain );
151
- $ originalChain = $ this ->chain ;
152
151
while ($ this ->getState () !== PromiseState::PENDING ) {
153
152
$ chainItem = $ this ->getNextChainItem ();
154
153
if (!$ chainItem ) {
@@ -160,17 +159,15 @@ function(Chainable $a, Chainable $b) {
160
159
}
161
160
elseif ($ chainItem instanceof CatchChain) {
162
161
if ($ handled = $ this ->handleCatch ($ chainItem )) {
163
- array_push ($ handledRejections , $ handled );
162
+ array_push ($ this -> handledRejections , $ handled );
164
163
}
165
164
}
166
165
elseif ($ chainItem instanceof FinallyChain) {
167
166
$ this ->handleFinally ($ chainItem );
168
167
}
169
168
}
170
169
171
- $ this ->handleCatches ($ originalChain , $ emptyChain , $ handledRejections );
172
-
173
- $ this ->completed = true ;
170
+ $ this ->throwUnhandledRejection ();
174
171
}
175
172
176
173
private function getNextChainItem ():?Chainable {
@@ -200,7 +197,8 @@ private function handleThen(ThenChain $then):void {
200
197
201
198
private function handleCatch (CatchChain $ catch ):?Throwable {
202
199
if ($ this ->getState () !== PromiseState::REJECTED ) {
203
- // TODO: This is where #52 can be implemented.
200
+ // TODO: This is where #52 can be implemented
201
+ // see: (https://github.com/PhpGt/Promise/issues/52)
204
202
array_push ($ this ->uncalledCatchChain , $ catch );
205
203
return null ;
206
204
}
@@ -244,29 +242,9 @@ private function handleFinally(FinallyChain $finally):void {
244
242
}
245
243
}
246
244
247
- /**
248
- * @param array<Chainable> $chain
249
- * @param bool $emptyChain
250
- * @param array<Throwable> $handledRejections
251
- */
252
- protected function handleCatches (
253
- array $ chain ,
254
- bool $ emptyChain ,
255
- array $ handledRejections ,
256
- ):void {
257
- if ($ this ->getState () === PromiseState::REJECTED ) {
258
- $ hasCatch = false ;
259
- foreach ($ chain as $ chainItem ) {
260
- if ($ chainItem instanceof CatchChain) {
261
- $ hasCatch = true ;
262
- }
263
- }
264
-
265
- if (!$ hasCatch ) {
266
- throw $ this ->rejectedReason ;
267
- }
268
-
269
- if (!$ emptyChain && !in_array ($ this ->rejectedReason , $ handledRejections )) {
245
+ protected function throwUnhandledRejection ():void {
246
+ if ($ this ->getState () === PromiseState::REJECTED ) {
247
+ if (!in_array ($ this ->rejectedReason , $ this ->handledRejections )) {
270
248
throw $ this ->rejectedReason ;
271
249
}
272
250
}
0 commit comments