Open Journal Systems  3.3.0
Coroutine.php
1 <?php
2 namespace GuzzleHttp\Promise;
3 
4 use Exception;
5 use Generator;
6 use Throwable;
7 
43 final class Coroutine implements PromiseInterface
44 {
48  private $currentPromise;
49 
53  private $generator;
54 
58  private $result;
59 
60  public function __construct(callable $generatorFn)
61  {
62  $this->generator = $generatorFn();
63  $this->result = new Promise(function () {
64  while (isset($this->currentPromise)) {
65  $this->currentPromise->wait();
66  }
67  });
68  $this->nextCoroutine($this->generator->current());
69  }
70 
71  public function then(
72  callable $onFulfilled = null,
73  callable $onRejected = null
74  ) {
75  return $this->result->then($onFulfilled, $onRejected);
76  }
77 
78  public function otherwise(callable $onRejected)
79  {
80  return $this->result->otherwise($onRejected);
81  }
82 
83  public function wait($unwrap = true)
84  {
85  return $this->result->wait($unwrap);
86  }
87 
88  public function getState()
89  {
90  return $this->result->getState();
91  }
92 
93  public function resolve($value)
94  {
95  $this->result->resolve($value);
96  }
97 
98  public function reject($reason)
99  {
100  $this->result->reject($reason);
101  }
102 
103  public function cancel()
104  {
105  $this->currentPromise->cancel();
106  $this->result->cancel();
107  }
108 
109  private function nextCoroutine($yielded)
110  {
111  $this->currentPromise = promise_for($yielded)
112  ->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
113  }
114 
118  public function _handleSuccess($value)
119  {
120  unset($this->currentPromise);
121  try {
122  $next = $this->generator->send($value);
123  if ($this->generator->valid()) {
124  $this->nextCoroutine($next);
125  } else {
126  $this->result->resolve($value);
127  }
128  } catch (Exception $exception) {
129  $this->result->reject($exception);
130  } catch (Throwable $throwable) {
131  $this->result->reject($throwable);
132  }
133  }
134 
138  public function _handleFailure($reason)
139  {
140  unset($this->currentPromise);
141  try {
142  $nextYield = $this->generator->throw(exception_for($reason));
143  // The throw was caught, so keep iterating on the coroutine
144  $this->nextCoroutine($nextYield);
145  } catch (Exception $exception) {
146  $this->result->reject($exception);
147  } catch (Throwable $throwable) {
148  $this->result->reject($throwable);
149  }
150  }
151 }
GuzzleHttp\Promise\promise_for
promise_for($value)
Definition: guzzlehttp/promises/src/functions.php:66
GuzzleHttp\Promise\Coroutine\otherwise
otherwise(callable $onRejected)
Definition: Coroutine.php:87
GuzzleHttp\Promise\Coroutine\then
then(callable $onFulfilled=null, callable $onRejected=null)
Definition: Coroutine.php:80
GuzzleHttp\Promise\Coroutine\reject
reject($reason)
Definition: Coroutine.php:107
GuzzleHttp\Promise\PromiseInterface
Definition: PromiseInterface.php:13
GuzzleHttp\Promise\Coroutine\_handleSuccess
_handleSuccess($value)
Definition: Coroutine.php:127
GuzzleHttp\Promise\Coroutine\wait
wait($unwrap=true)
Definition: Coroutine.php:92
GuzzleHttp\Promise\Coroutine\getState
getState()
Definition: Coroutine.php:97
GuzzleHttp\Promise\Coroutine
Definition: Coroutine.php:43
GuzzleHttp\Promise\Coroutine\_handleFailure
_handleFailure($reason)
Definition: Coroutine.php:147
GuzzleHttp\Promise\Coroutine\resolve
resolve($value)
Definition: Coroutine.php:102
GuzzleHttp\Promise\Coroutine\__construct
__construct(callable $generatorFn)
Definition: Coroutine.php:69
GuzzleHttp\Promise\Promise
Definition: guzzlehttp/promises/src/Promise.php:9
GuzzleHttp\Promise
Definition: AggregateException.php:2
GuzzleHttp\Promise\Coroutine\cancel
cancel()
Definition: Coroutine.php:112
GuzzleHttp\Promise\exception_for
exception_for($reason)
Definition: guzzlehttp/promises/src/functions.php:108