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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Coroutine.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 4.24 KiB


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