PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / libraries / http / client-common / Deferred.php

Deferred.php in DecaLog 4.4.0, at includes/libraries/http/client-common/Deferred.php

156 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Http\Client\Common;
6
7 use Http\Promise\Promise;
8 use Psr\Http\Client\ClientExceptionInterface;
9 use Psr\Http\Message\ResponseInterface;
10
11 /**
12 * A deferred allow to return a promise which has not been resolved yet.
13 */
14 final class Deferred implements Promise
15 {
16 /**
17 * @var ResponseInterface|null
18 */
19 private $value;
20
21 /**
22 * @var ClientExceptionInterface|null
23 */
24 private $failure;
25
26 /**
27 * @var string
28 */
29 private $state;
30
31 /**
32 * @var callable
33 */
34 private $waitCallback;
35
36 /**
37 * @var callable[]
38 */
39 private $onFulfilledCallbacks;
40
41 /**
42 * @var callable[]
43 */
44 private $onRejectedCallbacks;
45
46 public function __construct(callable $waitCallback)
47 {
48 $this->waitCallback = $waitCallback;
49 $this->state = Promise::PENDING;
50 $this->onFulfilledCallbacks = [];
51 $this->onRejectedCallbacks = [];
52 }
53
54 /**
55 * {@inheritdoc}
56 */
57 public function then(callable $onFulfilled = null, callable $onRejected = null): Promise
58 {
59 $deferred = new self($this->waitCallback);
60
61 $this->onFulfilledCallbacks[] = function (ResponseInterface $response) use ($onFulfilled, $deferred) {
62 try {
63 if (null !== $onFulfilled) {
64 $response = $onFulfilled($response);
65 }
66 $deferred->resolve($response);
67 } catch (ClientExceptionInterface $exception) {
68 $deferred->reject($exception);
69 }
70 };
71
72 $this->onRejectedCallbacks[] = function (ClientExceptionInterface $exception) use ($onRejected, $deferred) {
73 try {
74 if (null !== $onRejected) {
75 $response = $onRejected($exception);
76 $deferred->resolve($response);
77
78 return;
79 }
80 $deferred->reject($exception);
81 } catch (ClientExceptionInterface $newException) {
82 $deferred->reject($newException);
83 }
84 };
85
86 return $deferred;
87 }
88
89 /**
90 * {@inheritdoc}
91 */
92 public function getState(): string
93 {
94 return $this->state;
95 }
96
97 /**
98 * Resolve this deferred with a Response.
99 */
100 public function resolve(ResponseInterface $response): void
101 {
102 if (Promise::PENDING !== $this->state) {
103 return;
104 }
105
106 $this->value = $response;
107 $this->state = Promise::FULFILLED;
108
109 foreach ($this->onFulfilledCallbacks as $onFulfilledCallback) {
110 $onFulfilledCallback($response);
111 }
112 }
113
114 /**
115 * Reject this deferred with an Exception.
116 */
117 public function reject(ClientExceptionInterface $exception): void
118 {
119 if (Promise::PENDING !== $this->state) {
120 return;
121 }
122
123 $this->failure = $exception;
124 $this->state = Promise::REJECTED;
125
126 foreach ($this->onRejectedCallbacks as $onRejectedCallback) {
127 $onRejectedCallback($exception);
128 }
129 }
130
131 /**
132 * {@inheritdoc}
133 */
134 public function wait($unwrap = true)
135 {
136 if (Promise::PENDING === $this->state) {
137 $callback = $this->waitCallback;
138 $callback();
139 }
140
141 if (!$unwrap) {
142 return null;
143 }
144
145 if (Promise::FULFILLED === $this->state) {
146 return $this->value;
147 }
148
149 if (null === $this->failure) {
150 throw new \RuntimeException('Internal Error: Promise is not fulfilled but has no exception stored');
151 }
152
153 throw $this->failure;
154 }
155 }
156