PluginProbe
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more / 2.5.7
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more v2.5.7
3.7.2 3.7.1 3.7.0 3.6.0 3.6.1 3.5.2 trunk 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.6.0 2.6.1 All 73 releases
stockpack / vendor / guzzlehttp / promises / src / Coroutine.php

Coroutine.php in StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more 2.5.7, at vendor/guzzlehttp/promises/src/Coroutine.php

152 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace GuzzleHttp\Promise;
3
4 use Exception;
5 use Generator;
6 use Throwable;
7
8 /**
9 * Creates a promise that is resolved using a generator that yields values or
10 * promises (somewhat similar to C#'s async keyword).
11 *
12 * When called, the coroutine function will start an instance of the generator
13 * and returns a promise that is fulfilled with its final yielded value.
14 *
15 * Control is returned back to the generator when the yielded promise settles.
16 * This can lead to less verbose code when doing lots of sequential async calls
17 * with minimal processing in between.
18 *
19 * use GuzzleHttp\Promise;
20 *
21 * function createPromise($value) {
22 * return new Promise\FulfilledPromise($value);
23 * }
24 *
25 * $promise = Promise\coroutine(function () {
26 * $value = (yield createPromise('a'));
27 * try {
28 * $value = (yield createPromise($value . 'b'));
29 * } catch (\Exception $e) {
30 * // The promise was rejected.
31 * }
32 * yield $value . 'c';
33 * });
34 *
35 * // Outputs "abc"
36 * $promise->then(function ($v) { echo $v; });
37 *
38 * @param callable $generatorFn Generator function to wrap into a promise.
39 *
40 * @return Promise
41 * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
42 */
43 final class Coroutine implements PromiseInterface
44 {
45 /**
46 * @var PromiseInterface|null
47 */
48 private $currentPromise;
49
50 /**
51 * @var Generator
52 */
53 private $generator;
54
55 /**
56 * @var Promise
57 */
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
115 /**
116 * @internal
117 */
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
135 /**
136 * @internal
137 */
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 }
152