Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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: 01.05.2026, 11:26 - 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