Skip to content

Commit 53f636f

Browse files
author
Greg Bowler
committed
tidy: refactor away complexity
1 parent f5af9ab commit 53f636f

File tree

2 files changed

+96
-59
lines changed

2 files changed

+96
-59
lines changed

src/ExecutesPromiseChain.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
namespace Gt\Promise;
3+
4+
use Gt\Promise\Chain\CatchChain;
5+
use Gt\Promise\Chain\Chainable;
6+
use Gt\Promise\Chain\ChainFunctionTypeError;
7+
use Gt\Promise\Chain\FinallyChain;
8+
use Gt\Promise\Chain\ThenChain;
9+
10+
trait ExecutesPromiseChain {
11+
private function complete():void {
12+
usort($this->chain, $this->sortChainItems(...));
13+
14+
while($this->getState() !== PromiseState::PENDING) {
15+
$chainItem = $this->getNextChainItem();
16+
if(!$chainItem) {
17+
break;
18+
}
19+
20+
if($this->shouldSkipResolution($chainItem)) {
21+
continue;
22+
}
23+
24+
if($chainItem instanceof ThenChain) {
25+
$this->executeThen($chainItem);
26+
}
27+
elseif($chainItem instanceof FinallyChain) {
28+
$this->executeFinally($chainItem);
29+
}
30+
elseif($chainItem instanceof CatchChain) {
31+
$this->executeCatch($chainItem);
32+
}
33+
}
34+
35+
$this->throwUnhandledRejection();
36+
}
37+
38+
private function shouldSkipResolution(Chainable $chainItem):bool {
39+
if($chainItem instanceof ThenChain || $chainItem instanceof FinallyChain) {
40+
try {
41+
if($this->resolvedValueSet && isset($this->resolvedValue)) {
42+
$chainItem->checkResolutionCallbackType($this->resolvedValue);
43+
}
44+
}
45+
catch(ChainFunctionTypeError) {
46+
return true;
47+
}
48+
}
49+
elseif($chainItem instanceof CatchChain) {
50+
try {
51+
if(isset($this->rejectedReason)) {
52+
$chainItem->checkRejectionCallbackType($this->rejectedReason);
53+
}
54+
}
55+
catch(ChainFunctionTypeError) {
56+
return true;
57+
}
58+
}
59+
return false;
60+
}
61+
62+
private function executeThen(ThenChain $chainItem):void {
63+
if($this->handleThen($chainItem)) {
64+
$this->emptyChain();
65+
}
66+
}
67+
68+
private function executeFinally(FinallyChain $chainItem):void {
69+
if($this->handleFinally($chainItem)) {
70+
$this->emptyChain();
71+
}
72+
}
73+
74+
private function executeCatch(CatchChain $chainItem):void {
75+
if($handled = $this->handleCatch($chainItem)) {
76+
array_push($this->handledRejections, $handled);
77+
}
78+
}
79+
80+
private function sortChainItems(Chainable $a, Chainable $b):int {
81+
if($a instanceof FinallyChain && !($b instanceof FinallyChain)) {
82+
return 1;
83+
}
84+
if($b instanceof FinallyChain && !($a instanceof FinallyChain)) {
85+
return -1;
86+
}
87+
return 0;
88+
}
89+
}

src/Promise.php

Lines changed: 7 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,23 @@
99
use Throwable;
1010

1111
class Promise implements PromiseInterface {
12+
use ExecutesPromiseChain;
13+
1214
private bool $resolvedValueSet = false;
1315
private bool $stopChain = false;
1416

1517
private mixed $resolvedValue;
1618
private mixed $originalResolvedValue;
1719
private Throwable $rejectedReason;
20+
/** @var array<Chainable> */
1821
private array $chain;
19-
private array $uncalledCatchChain;
22+
/** @var array<Throwable> */
2023
private array $handledRejections;
2124
/** @var callable */
2225
private $executor;
2326

2427
public function __construct(callable $executor) {
2528
$this->chain = [];
26-
$this->uncalledCatchChain = [];
2729
$this->handledRejections = [];
2830
$this->executor = $executor;
2931
$this->callExecutor();
@@ -131,64 +133,11 @@ private function tryComplete():void {
131133
}
132134
}
133135

134-
private function complete():void {
135-
usort(
136-
$this->chain,
137-
function(Chainable $a, Chainable $b) {
138-
if($a instanceof FinallyChain && !($b instanceof FinallyChain)) return 1;
139-
if($b instanceof FinallyChain && !($a instanceof FinallyChain)) return -1;
140-
return 0;
141-
}
142-
);
143-
144-
while ($this->getState() !== PromiseState::PENDING) {
145-
$chainItem = $this->getNextChainItem();
146-
if (!$chainItem) break;
147-
148-
if ($chainItem instanceof ThenChain || $chainItem instanceof FinallyChain) {
149-
try {
150-
if($this->resolvedValueSet && isset($this->resolvedValue)) {
151-
$chainItem->checkResolutionCallbackType($this->resolvedValue);
152-
}
153-
}
154-
catch (ChainFunctionTypeError) {
155-
continue;
156-
}
157-
158-
if($chainItem instanceof ThenChain) {
159-
if ($this->handleThen($chainItem)) {
160-
$this->emptyChain();
161-
}
162-
}
163-
elseif($chainItem instanceof FinallyChain) {
164-
if($this->handleFinally($chainItem)) {
165-
$this->emptyChain();
166-
}
167-
}
168-
}
169-
elseif ($chainItem instanceof CatchChain) {
170-
try {
171-
if (isset($this->rejectedReason)) {
172-
$chainItem->checkRejectionCallbackType($this->rejectedReason);
173-
}
174-
if ($handled = $this->handleCatch($chainItem)) {
175-
array_push($this->handledRejections, $handled);
176-
}
177-
}
178-
catch (ChainFunctionTypeError) {
179-
continue;
180-
}
181-
}
182-
}
183-
184-
$this->throwUnhandledRejection();
185-
}
186-
187136
private function getNextChainItem():?Chainable {
188137
return array_shift($this->chain);
189138
}
190139

191-
private function handleThen(ThenChain $then):bool {
140+
protected function handleThen(ThenChain $then):bool {
192141
if($this->getState() !== PromiseState::RESOLVED) {
193142
return false;
194143
}
@@ -204,7 +153,7 @@ private function handleThen(ThenChain $then):bool {
204153
return false;
205154
}
206155

207-
private function handleFinally(FinallyChain $finally):bool {
156+
protected function handleFinally(FinallyChain $finally):bool {
208157
if($this->getState() === PromiseState::RESOLVED) {
209158
$result = $finally->callOnResolved($this->resolvedValue);
210159
return $this->handleResolvedResult($result);
@@ -234,9 +183,8 @@ private function handleResolvedResult(mixed $result):bool {
234183
return false;
235184
}
236185

237-
private function handleCatch(CatchChain $catch):?Throwable {
186+
protected function handleCatch(CatchChain $catch):?Throwable {
238187
if($this->getState() !== PromiseState::REJECTED) {
239-
array_push($this->uncalledCatchChain, $catch);
240188
return null;
241189
}
242190
try {

0 commit comments

Comments
 (0)