@@ -15,14 +15,15 @@ class Promise implements PromiseInterface {
1515 private array $ chain ;
1616 /** @var CatchChain[] */
1717 private array $ uncalledCatchChain ;
18+ /** @var Throwable[] */
19+ private array $ handledRejections ;
1820 /** @var callable */
1921 private $ executor ;
20- private bool $ completed ;
2122
2223 public function __construct (callable $ executor ) {
23- $ this ->completed = false ;
2424 $ this ->chain = [];
2525 $ this ->uncalledCatchChain = [];
26+ $ this ->handledRejections = [];
2627
2728 $ this ->executor = $ executor ;
2829 $ this ->callExecutor ();
@@ -123,7 +124,8 @@ private function reset():void {
123124 }
124125
125126 private function tryComplete ():void {
126- if (empty ($ this ->chain ) && $ this ->getState () === PromiseState::PENDING ) {
127+ if (empty ($ this ->chain )) {
128+ $ this ->throwUnhandledRejection ();
127129 return ;
128130 }
129131 if ($ this ->getState () !== PromiseState::PENDING ) {
@@ -145,10 +147,7 @@ function(Chainable $a, Chainable $b) {
145147 return 0 ;
146148 }
147149 );
148- $ handledRejections = [];
149150
150- $ emptyChain = empty ($ this ->chain );
151- $ originalChain = $ this ->chain ;
152151 while ($ this ->getState () !== PromiseState::PENDING ) {
153152 $ chainItem = $ this ->getNextChainItem ();
154153 if (!$ chainItem ) {
@@ -160,17 +159,15 @@ function(Chainable $a, Chainable $b) {
160159 }
161160 elseif ($ chainItem instanceof CatchChain) {
162161 if ($ handled = $ this ->handleCatch ($ chainItem )) {
163- array_push ($ handledRejections , $ handled );
162+ array_push ($ this -> handledRejections , $ handled );
164163 }
165164 }
166165 elseif ($ chainItem instanceof FinallyChain) {
167166 $ this ->handleFinally ($ chainItem );
168167 }
169168 }
170169
171- $ this ->handleCatches ($ originalChain , $ emptyChain , $ handledRejections );
172-
173- $ this ->completed = true ;
170+ $ this ->throwUnhandledRejection ();
174171 }
175172
176173 private function getNextChainItem ():?Chainable {
@@ -200,7 +197,8 @@ private function handleThen(ThenChain $then):void {
200197
201198 private function handleCatch (CatchChain $ catch ):?Throwable {
202199 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)
204202 array_push ($ this ->uncalledCatchChain , $ catch );
205203 return null ;
206204 }
@@ -244,29 +242,9 @@ private function handleFinally(FinallyChain $finally):void {
244242 }
245243 }
246244
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 )) {
270248 throw $ this ->rejectedReason ;
271249 }
272250 }
0 commit comments