Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Coroutine.php
001 <?php
002
003 namespace GuzzleHttp\Promise;
004
005 use Exception;
006 use Generator;
007 use Throwable;
008
009 /**
010 * Creates a promise that is resolved using a generator that yields values or
011 * promises (somewhat similar to C#'s async keyword).
012 *
013 * When called, the Coroutine::of method will start an instance of the generator
014 * and returns a promise that is fulfilled with its final yielded value.
015 *
016 * Control is returned back to the generator when the yielded promise settles.
017 * This can lead to less verbose code when doing lots of sequential async calls
018 * with minimal processing in between.
019 *
020 * use GuzzleHttp\Promise;
021 *
022 * function createPromise($value) {
023 * return new Promise\FulfilledPromise($value);
024 * }
025 *
026 * $promise = Promise\Coroutine::of(function () {
027 * $value = (yield createPromise('a'));
028 * try {
029 * $value = (yield createPromise($value . 'b'));
030 * } catch (\Exception $e) {
031 * // The promise was rejected.
032 * }
033 * yield $value . 'c';
034 * });
035 *
036 * // Outputs "abc"
037 * $promise->then(function ($v) { echo $v; });
038 *
039 * @param callable $generatorFn Generator function to wrap into a promise.
040 *
041 * @return Promise
042 *
043 * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
044 */
045 final class Coroutine implements PromiseInterface
046 {
047 /**
048 * @var PromiseInterface|null
049 */
050 private $currentPromise;
051
052 /**
053 * @var Generator
054 */
055 private $generator;
056
057 /**
058 * @var Promise
059 */
060 private $result;
061
062 public function __construct(callable $generatorFn)
063 {
064 $this->generator = $generatorFn();
065 $this->result = new Promise(function () {
066 while (isset($this->currentPromise)) {
067 $this->currentPromise->wait();
068 }
069 });
070 try {
071 $this->nextCoroutine($this->generator->current());
072 } catch (\Exception $exception) {
073 $this->result->reject($exception);
074 } catch (Throwable $throwable) {
075 $this->result->reject($throwable);
076 }
077 }
078
079 /**
080 * Create a new coroutine.
081 *
082 * @return self
083 */
084 public static function of(callable $generatorFn)
085 {
086 return new self($generatorFn);
087 }
088
089 public function then(
090 callable $onFulfilled = null,
091 callable $onRejected = null
092 ) {
093 return $this->result->then($onFulfilled, $onRejected);
094 }
095
096 public function otherwise(callable $onRejected)
097 {
098 return $this->result->otherwise($onRejected);
099 }
100
101 public function wait($unwrap = true)
102 {
103 return $this->result->wait($unwrap);
104 }
105
106 public function getState()
107 {
108 return $this->result->getState();
109 }
110
111 public function resolve($value)
112 {
113 $this->result->resolve($value);
114 }
115
116 public function reject($reason)
117 {
118 $this->result->reject($reason);
119 }
120
121 public function cancel()
122 {
123 $this->currentPromise->cancel();
124 $this->result->cancel();
125 }
126
127 private function nextCoroutine($yielded)
128 {
129 $this->currentPromise = Create::promiseFor($yielded)
130 ->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
131 }
132
133 /**
134 * @internal
135 */
136 public function _handleSuccess($value)
137 {
138 unset($this->currentPromise);
139 try {
140 $next = $this->generator->send($value);
141 if ($this->generator->valid()) {
142 $this->nextCoroutine($next);
143 } else {
144 $this->result->resolve($value);
145 }
146 } catch (Exception $exception) {
147 $this->result->reject($exception);
148 } catch (Throwable $throwable) {
149 $this->result->reject($throwable);
150 }
151 }
152
153 /**
154 * @internal
155 */
156 public function _handleFailure($reason)
157 {
158 unset($this->currentPromise);
159 try {
160 $nextYield = $this->generator->throw(Create::exceptionFor($reason));
161 // The throw was caught, so keep iterating on the coroutine
162 $this->nextCoroutine($nextYield);
163 } catch (Exception $exception) {
164 $this->result->reject($exception);
165 } catch (Throwable $throwable) {
166 $this->result->reject($throwable);
167 }
168 }
169 }
170