Browse code

added appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:35:09
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,559 @@
1
+# Guzzle Promises
2
+
3
+[Promises/A+](https://promisesaplus.com/) implementation that handles promise
4
+chaining and resolution iteratively, allowing for "infinite" promise chaining
5
+while keeping the stack size constant. Read [this blog post](https://blog.domenic.me/youre-missing-the-point-of-promises/)
6
+for a general introduction to promises.
7
+
8
+- [Features](#features)
9
+- [Quick start](#quick-start)
10
+- [Synchronous wait](#synchronous-wait)
11
+- [Cancellation](#cancellation)
12
+- [API](#api)
13
+  - [Promise](#promise)
14
+  - [FulfilledPromise](#fulfilledpromise)
15
+  - [RejectedPromise](#rejectedpromise)
16
+- [Promise interop](#promise-interop)
17
+- [Implementation notes](#implementation-notes)
18
+
19
+
20
+## Features
21
+
22
+- [Promises/A+](https://promisesaplus.com/) implementation.
23
+- Promise resolution and chaining is handled iteratively, allowing for
24
+  "infinite" promise chaining.
25
+- Promises have a synchronous `wait` method.
26
+- Promises can be cancelled.
27
+- Works with any object that has a `then` function.
28
+- C# style async/await coroutine promises using
29
+  `GuzzleHttp\Promise\Coroutine::of()`.
30
+
31
+
32
+## Installation
33
+
34
+```shell
35
+composer require guzzlehttp/promises
36
+```
37
+
38
+
39
+## Version Guidance
40
+
41
+| Version | Status              | PHP Version  |
42
+|---------|---------------------|--------------|
43
+| 1.x     | Security fixes only | >=5.5,<8.3   |
44
+| 2.x     | Latest              | >=7.2.5,<8.6 |
45
+
46
+
47
+## Quick Start
48
+
49
+A *promise* represents the eventual result of an asynchronous operation. The
50
+primary way of interacting with a promise is through its `then` method, which
51
+registers callbacks to receive either a promise's eventual value or the reason
52
+why the promise cannot be fulfilled.
53
+
54
+### Callbacks
55
+
56
+Callbacks are registered with the `then` method by providing an optional 
57
+`$onFulfilled` followed by an optional `$onRejected` function.
58
+
59
+
60
+```php
61
+use GuzzleHttp\Promise\Promise;
62
+
63
+$promise = new Promise();
64
+$promise->then(
65
+    // $onFulfilled
66
+    function ($value) {
67
+        echo 'The promise was fulfilled.';
68
+    },
69
+    // $onRejected
70
+    function ($reason) {
71
+        echo 'The promise was rejected.';
72
+    }
73
+);
74
+```
75
+
76
+*Resolving* a promise means that you either fulfill a promise with a *value* or
77
+reject a promise with a *reason*. Resolving a promise triggers callbacks
78
+registered with the promise's `then` method. These callbacks are triggered
79
+only once and in the order in which they were added.
80
+
81
+### Resolving a Promise
82
+
83
+Promises are fulfilled using the `resolve($value)` method. Resolving a promise
84
+with any value other than a `GuzzleHttp\Promise\RejectedPromise` will trigger
85
+all of the onFulfilled callbacks (resolving a promise with a rejected promise
86
+will reject the promise and trigger the `$onRejected` callbacks).
87
+
88
+```php
89
+use GuzzleHttp\Promise\Promise;
90
+
91
+$promise = new Promise();
92
+$promise
93
+    ->then(function ($value) {
94
+        // Return a value and don't break the chain
95
+        return "Hello, " . $value;
96
+    })
97
+    // This then is executed after the first then and receives the value
98
+    // returned from the first then.
99
+    ->then(function ($value) {
100
+        echo $value;
101
+    });
102
+
103
+// Resolving the promise triggers the $onFulfilled callbacks and outputs
104
+// "Hello, reader."
105
+$promise->resolve('reader.');
106
+```
107
+
108
+### Promise Forwarding
109
+
110
+Promises can be chained one after the other. Each then in the chain is a new
111
+promise. The return value of a promise is what's forwarded to the next
112
+promise in the chain. Returning a promise in a `then` callback will cause the
113
+subsequent promises in the chain to only be fulfilled when the returned promise
114
+has been fulfilled. The next promise in the chain will be invoked with the
115
+resolved value of the promise.
116
+
117
+```php
118
+use GuzzleHttp\Promise\Promise;
119
+
120
+$promise = new Promise();
121
+$nextPromise = new Promise();
122
+
123
+$promise
124
+    ->then(function ($value) use ($nextPromise) {
125
+        echo $value;
126
+        return $nextPromise;
127
+    })
128
+    ->then(function ($value) {
129
+        echo $value;
130
+    });
131
+
132
+// Triggers the first callback and outputs "A"
133
+$promise->resolve('A');
134
+// Triggers the second callback and outputs "B"
135
+$nextPromise->resolve('B');
136
+```
137
+
138
+### Promise Rejection
139
+
140
+When a promise is rejected, the `$onRejected` callbacks are invoked with the
141
+rejection reason.
142
+
143
+```php
144
+use GuzzleHttp\Promise\Promise;
145
+
146
+$promise = new Promise();
147
+$promise->then(null, function ($reason) {
148
+    echo $reason;
149
+});
150
+
151
+$promise->reject('Error!');
152
+// Outputs "Error!"
153
+```
154
+
155
+### Rejection Forwarding
156
+
157
+If an exception is thrown in an `$onRejected` callback, subsequent
158
+`$onRejected` callbacks are invoked with the thrown exception as the reason.
159
+
160
+```php
161
+use GuzzleHttp\Promise\Promise;
162
+
163
+$promise = new Promise();
164
+$promise->then(null, function ($reason) {
165
+    throw new Exception($reason);
166
+})->then(null, function ($reason) {
167
+    assert($reason->getMessage() === 'Error!');
168
+});
169
+
170
+$promise->reject('Error!');
171
+```
172
+
173
+You can also forward a rejection down the promise chain by returning a
174
+`GuzzleHttp\Promise\RejectedPromise` in either an `$onFulfilled` or
175
+`$onRejected` callback.
176
+
177
+```php
178
+use GuzzleHttp\Promise\Promise;
179
+use GuzzleHttp\Promise\RejectedPromise;
180
+
181
+$promise = new Promise();
182
+$promise->then(null, function ($reason) {
183
+    return new RejectedPromise($reason);
184
+})->then(null, function ($reason) {
185
+    assert($reason === 'Error!');
186
+});
187
+
188
+$promise->reject('Error!');
189
+```
190
+
191
+If an exception is not thrown in a `$onRejected` callback and the callback
192
+does not return a rejected promise, downstream `$onFulfilled` callbacks are
193
+invoked using the value returned from the `$onRejected` callback.
194
+
195
+```php
196
+use GuzzleHttp\Promise\Promise;
197
+
198
+$promise = new Promise();
199
+$promise
200
+    ->then(null, function ($reason) {
201
+        return "It's ok";
202
+    })
203
+    ->then(function ($value) {
204
+        assert($value === "It's ok");
205
+    });
206
+
207
+$promise->reject('Error!');
208
+```
209
+
210
+
211
+## Synchronous Wait
212
+
213
+You can synchronously force promises to complete using a promise's `wait`
214
+method. When creating a promise, you can provide a wait function that is used
215
+to synchronously force a promise to complete. When a wait function is invoked
216
+it is expected to deliver a value to the promise or reject the promise. If the
217
+wait function does not deliver a value, then an exception is thrown. The wait
218
+function provided to a promise constructor is invoked when the `wait` function
219
+of the promise is called.
220
+
221
+```php
222
+$promise = new Promise(function () use (&$promise) {
223
+    $promise->resolve('foo');
224
+});
225
+
226
+// Calling wait will return the value of the promise.
227
+echo $promise->wait(); // outputs "foo"
228
+```
229
+
230
+If an exception is encountered while invoking the wait function of a promise,
231
+the promise is rejected with the exception and the exception is thrown.
232
+
233
+```php
234
+$promise = new Promise(function () use (&$promise) {
235
+    throw new Exception('foo');
236
+});
237
+
238
+$promise->wait(); // throws the exception.
239
+```
240
+
241
+Calling `wait` on a promise that has been fulfilled will not trigger the wait
242
+function. It will simply return the previously resolved value.
243
+
244
+```php
245
+$promise = new Promise(function () { die('this is not called!'); });
246
+$promise->resolve('foo');
247
+echo $promise->wait(); // outputs "foo"
248
+```
249
+
250
+Calling `wait` on a promise that has been rejected will throw an exception. If
251
+the rejection reason is an instance of `\Exception` the reason is thrown.
252
+Otherwise, a `GuzzleHttp\Promise\RejectionException` is thrown and the reason
253
+can be obtained by calling the `getReason` method of the exception.
254
+
255
+```php
256
+$promise = new Promise();
257
+$promise->reject('foo');
258
+$promise->wait();
259
+```
260
+
261
+> PHP Fatal error:  Uncaught exception 'GuzzleHttp\Promise\RejectionException' with message 'The promise was rejected with value: foo'
262
+
263
+### Unwrapping a Promise
264
+
265
+When synchronously waiting on a promise, you are joining the state of the
266
+promise into the current state of execution (i.e., return the value of the
267
+promise if it was fulfilled or throw an exception if it was rejected). This is
268
+called "unwrapping" the promise. Waiting on a promise will by default unwrap
269
+the promise state.
270
+
271
+You can force a promise to resolve and *not* unwrap the state of the promise
272
+by passing `false` to the first argument of the `wait` function:
273
+
274
+```php
275
+$promise = new Promise();
276
+$promise->reject('foo');
277
+// This will not throw an exception. It simply ensures the promise has
278
+// been resolved.
279
+$promise->wait(false);
280
+```
281
+
282
+When unwrapping a promise, the resolved value of the promise will be waited
283
+upon until the unwrapped value is not a promise. This means that if you resolve
284
+promise A with a promise B and unwrap promise A, the value returned by the
285
+wait function will be the value delivered to promise B.
286
+
287
+**Note**: when you do not unwrap the promise, no value is returned.
288
+
289
+
290
+## Cancellation
291
+
292
+You can cancel a promise that has not yet been fulfilled using the `cancel()`
293
+method of a promise. When creating a promise you can provide an optional
294
+cancel function that when invoked cancels the action of computing a resolution
295
+of the promise.
296
+
297
+
298
+## API
299
+
300
+### Promise
301
+
302
+When creating a promise object, you can provide an optional `$waitFn` and
303
+`$cancelFn`. `$waitFn` is a function that is invoked with no arguments and is
304
+expected to resolve the promise. `$cancelFn` is a function with no arguments
305
+that is expected to cancel the computation of a promise. It is invoked when the
306
+`cancel()` method of a promise is called.
307
+
308
+```php
309
+use GuzzleHttp\Promise\Promise;
310
+
311
+$promise = new Promise(
312
+    function () use (&$promise) {
313
+        $promise->resolve('waited');
314
+    },
315
+    function () {
316
+        // do something that will cancel the promise computation (e.g., close
317
+        // a socket, cancel a database query, etc...)
318
+    }
319
+);
320
+
321
+assert('waited' === $promise->wait());
322
+```
323
+
324
+A promise has the following methods:
325
+
326
+- `then(callable $onFulfilled, callable $onRejected) : PromiseInterface`
327
+  
328
+  Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.
329
+
330
+- `otherwise(callable $onRejected) : PromiseInterface`
331
+  
332
+  Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
333
+
334
+- `wait($unwrap = true) : mixed`
335
+
336
+  Synchronously waits on the promise to complete.
337
+  
338
+  `$unwrap` controls whether or not the value of the promise is returned for a
339
+  fulfilled promise or if an exception is thrown if the promise is rejected.
340
+  This is set to `true` by default.
341
+
342
+- `cancel()`
343
+
344
+  Attempts to cancel the promise if possible. The promise being cancelled and
345
+  the parent most ancestor that has not yet been resolved will also be
346
+  cancelled. Any promises waiting on the cancelled promise to resolve will also
347
+  be cancelled.
348
+
349
+- `getState() : string`
350
+
351
+  Returns the state of the promise. One of `pending`, `fulfilled`, or
352
+  `rejected`.
353
+
354
+- `resolve($value)`
355
+
356
+  Fulfills the promise with the given `$value`.
357
+
358
+- `reject($reason)`
359
+
360
+  Rejects the promise with the given `$reason`.
361
+
362
+
363
+### FulfilledPromise
364
+
365
+A fulfilled promise can be created to represent a promise that has been
366
+fulfilled.
367
+
368
+```php
369
+use GuzzleHttp\Promise\FulfilledPromise;
370
+
371
+$promise = new FulfilledPromise('value');
372
+
373
+// Fulfilled callbacks are immediately invoked.
374
+$promise->then(function ($value) {
375
+    echo $value;
376
+});
377
+```
378
+
379
+
380
+### RejectedPromise
381
+
382
+A rejected promise can be created to represent a promise that has been
383
+rejected.
384
+
385
+```php
386
+use GuzzleHttp\Promise\RejectedPromise;
387
+
388
+$promise = new RejectedPromise('Error');
389
+
390
+// Rejected callbacks are immediately invoked.
391
+$promise->then(null, function ($reason) {
392
+    echo $reason;
393
+});
394
+```
395
+
396
+
397
+## Promise Interoperability
398
+
399
+This library works with foreign promises that have a `then` method. This means
400
+you can use Guzzle promises with [React promises](https://github.com/reactphp/promise)
401
+for example. When a foreign promise is returned inside of a then method
402
+callback, promise resolution will occur recursively.
403
+
404
+```php
405
+// Create a React promise
406
+$deferred = new React\Promise\Deferred();
407
+$reactPromise = $deferred->promise();
408
+
409
+// Create a Guzzle promise that is fulfilled with a React promise.
410
+$guzzlePromise = new GuzzleHttp\Promise\Promise();
411
+$guzzlePromise->then(function ($value) use ($reactPromise) {
412
+    // Do something something with the value...
413
+    // Return the React promise
414
+    return $reactPromise;
415
+});
416
+```
417
+
418
+Please note that wait and cancel chaining is no longer possible when forwarding
419
+a foreign promise. You will need to wrap a third-party promise with a Guzzle
420
+promise in order to utilize wait and cancel functions with foreign promises.
421
+
422
+
423
+### Event Loop Integration
424
+
425
+In order to keep the stack size constant, Guzzle promises are resolved
426
+asynchronously using a task queue. When waiting on promises synchronously, the
427
+task queue will be automatically run to ensure that the blocking promise and
428
+any forwarded promises are resolved. When using promises asynchronously in an
429
+event loop, you will need to run the task queue on each tick of the loop. If
430
+you do not run the task queue, then promises will not be resolved.
431
+
432
+You can run the task queue using the `run()` method of the global task queue
433
+instance.
434
+
435
+```php
436
+// Get the global task queue
437
+$queue = GuzzleHttp\Promise\Utils::queue();
438
+$queue->run();
439
+```
440
+
441
+For example, you could use Guzzle promises with React using a periodic timer:
442
+
443
+```php
444
+$loop = React\EventLoop\Factory::create();
445
+$loop->addPeriodicTimer(0, [$queue, 'run']);
446
+```
447
+
448
+
449
+## Implementation Notes
450
+
451
+### Promise Resolution and Chaining is Handled Iteratively
452
+
453
+By shuffling pending handlers from one owner to another, promises are
454
+resolved iteratively, allowing for "infinite" then chaining.
455
+
456
+```php
457
+<?php
458
+require 'vendor/autoload.php';
459
+
460
+use GuzzleHttp\Promise\Promise;
461
+
462
+$parent = new Promise();
463
+$p = $parent;
464
+
465
+for ($i = 0; $i < 1000; $i++) {
466
+    $p = $p->then(function ($v) {
467
+        // The stack size remains constant (a good thing)
468
+        echo xdebug_get_stack_depth() . ', ';
469
+        return $v + 1;
470
+    });
471
+}
472
+
473
+$parent->resolve(0);
474
+var_dump($p->wait()); // int(1000)
475
+
476
+```
477
+
478
+When a promise is fulfilled or rejected with a non-promise value, the promise
479
+then takes ownership of the handlers of each child promise and delivers values
480
+down the chain without using recursion.
481
+
482
+When a promise is resolved with another promise, the original promise transfers
483
+all of its pending handlers to the new promise. When the new promise is
484
+eventually resolved, all of the pending handlers are delivered the forwarded
485
+value.
486
+
487
+### A Promise is the Deferred
488
+
489
+Some promise libraries implement promises using a deferred object to represent
490
+a computation and a promise object to represent the delivery of the result of
491
+the computation. This is a nice separation of computation and delivery because
492
+consumers of the promise cannot modify the value that will be eventually
493
+delivered.
494
+
495
+One side effect of being able to implement promise resolution and chaining
496
+iteratively is that you need to be able for one promise to reach into the state
497
+of another promise to shuffle around ownership of handlers. In order to achieve
498
+this without making the handlers of a promise publicly mutable, a promise is
499
+also the deferred value, allowing promises of the same parent class to reach
500
+into and modify the private properties of promises of the same type. While this
501
+does allow consumers of the value to modify the resolution or rejection of the
502
+deferred, it is a small price to pay for keeping the stack size constant.
503
+
504
+```php
505
+$promise = new Promise();
506
+$promise->then(function ($value) { echo $value; });
507
+// The promise is the deferred value, so you can deliver a value to it.
508
+$promise->resolve('foo');
509
+// prints "foo"
510
+```
511
+
512
+
513
+## Upgrading from Function API
514
+
515
+A static API was first introduced in 1.4.0, in order to mitigate problems with
516
+functions conflicting between global and local copies of the package. The
517
+function API was removed in 2.0.0. A migration table has been provided here for
518
+your convenience:
519
+
520
+| Original Function | Replacement Method |
521
+|----------------|----------------|
522
+| `queue` | `Utils::queue` |
523
+| `task` | `Utils::task` |
524
+| `promise_for` | `Create::promiseFor` |
525
+| `rejection_for` | `Create::rejectionFor` |
526
+| `exception_for` | `Create::exceptionFor` |
527
+| `iter_for` | `Create::iterFor` |
528
+| `inspect` | `Utils::inspect` |
529
+| `inspect_all` | `Utils::inspectAll` |
530
+| `unwrap` | `Utils::unwrap` |
531
+| `all` | `Utils::all` |
532
+| `some` | `Utils::some` |
533
+| `any` | `Utils::any` |
534
+| `settle` | `Utils::settle` |
535
+| `each` | `Each::of` |
536
+| `each_limit` | `Each::ofLimit` |
537
+| `each_limit_all` | `Each::ofLimitAll` |
538
+| `!is_fulfilled` | `Is::pending` |
539
+| `is_fulfilled` | `Is::fulfilled` |
540
+| `is_rejected` | `Is::rejected` |
541
+| `is_settled` | `Is::settled` |
542
+| `coroutine` | `Coroutine::of` |
543
+
544
+
545
+## Security
546
+
547
+If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/promises/security/policy) for more information.
548
+
549
+
550
+## License
551
+
552
+Guzzle is made available under the MIT License (MIT). Please see [License File](LICENSE) for more information.
553
+
554
+
555
+## For Enterprise
556
+
557
+Available as part of the Tidelift Subscription
558
+
559
+The maintainers of Guzzle and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-guzzlehttp-promises?utm_source=packagist-guzzlehttp-promises&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
Browse code

removed appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:12:22
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,532 +0,0 @@
1
-# Guzzle Promises
2
-
3
-[Promises/A+](https://promisesaplus.com/) implementation that handles promise
4
-chaining and resolution iteratively, allowing for "infinite" promise chaining
5
-while keeping the stack size constant. Read [this blog post](https://blog.domenic.me/youre-missing-the-point-of-promises/)
6
-for a general introduction to promises.
7
-
8
-- [Features](#features)
9
-- [Quick start](#quick-start)
10
-- [Synchronous wait](#synchronous-wait)
11
-- [Cancellation](#cancellation)
12
-- [API](#api)
13
-  - [Promise](#promise)
14
-  - [FulfilledPromise](#fulfilledpromise)
15
-  - [RejectedPromise](#rejectedpromise)
16
-- [Promise interop](#promise-interop)
17
-- [Implementation notes](#implementation-notes)
18
-
19
-
20
-# Features
21
-
22
-- [Promises/A+](https://promisesaplus.com/) implementation.
23
-- Promise resolution and chaining is handled iteratively, allowing for
24
-  "infinite" promise chaining.
25
-- Promises have a synchronous `wait` method.
26
-- Promises can be cancelled.
27
-- Works with any object that has a `then` function.
28
-- C# style async/await coroutine promises using
29
-  `GuzzleHttp\Promise\Coroutine::of()`.
30
-
31
-
32
-# Quick start
33
-
34
-A *promise* represents the eventual result of an asynchronous operation. The
35
-primary way of interacting with a promise is through its `then` method, which
36
-registers callbacks to receive either a promise's eventual value or the reason
37
-why the promise cannot be fulfilled.
38
-
39
-
40
-## Callbacks
41
-
42
-Callbacks are registered with the `then` method by providing an optional 
43
-`$onFulfilled` followed by an optional `$onRejected` function.
44
-
45
-
46
-```php
47
-use GuzzleHttp\Promise\Promise;
48
-
49
-$promise = new Promise();
50
-$promise->then(
51
-    // $onFulfilled
52
-    function ($value) {
53
-        echo 'The promise was fulfilled.';
54
-    },
55
-    // $onRejected
56
-    function ($reason) {
57
-        echo 'The promise was rejected.';
58
-    }
59
-);
60
-```
61
-
62
-*Resolving* a promise means that you either fulfill a promise with a *value* or
63
-reject a promise with a *reason*. Resolving a promises triggers callbacks
64
-registered with the promises's `then` method. These callbacks are triggered
65
-only once and in the order in which they were added.
66
-
67
-
68
-## Resolving a promise
69
-
70
-Promises are fulfilled using the `resolve($value)` method. Resolving a promise
71
-with any value other than a `GuzzleHttp\Promise\RejectedPromise` will trigger
72
-all of the onFulfilled callbacks (resolving a promise with a rejected promise
73
-will reject the promise and trigger the `$onRejected` callbacks).
74
-
75
-```php
76
-use GuzzleHttp\Promise\Promise;
77
-
78
-$promise = new Promise();
79
-$promise
80
-    ->then(function ($value) {
81
-        // Return a value and don't break the chain
82
-        return "Hello, " . $value;
83
-    })
84
-    // This then is executed after the first then and receives the value
85
-    // returned from the first then.
86
-    ->then(function ($value) {
87
-        echo $value;
88
-    });
89
-
90
-// Resolving the promise triggers the $onFulfilled callbacks and outputs
91
-// "Hello, reader."
92
-$promise->resolve('reader.');
93
-```
94
-
95
-
96
-## Promise forwarding
97
-
98
-Promises can be chained one after the other. Each then in the chain is a new
99
-promise. The return value of a promise is what's forwarded to the next
100
-promise in the chain. Returning a promise in a `then` callback will cause the
101
-subsequent promises in the chain to only be fulfilled when the returned promise
102
-has been fulfilled. The next promise in the chain will be invoked with the
103
-resolved value of the promise.
104
-
105
-```php
106
-use GuzzleHttp\Promise\Promise;
107
-
108
-$promise = new Promise();
109
-$nextPromise = new Promise();
110
-
111
-$promise
112
-    ->then(function ($value) use ($nextPromise) {
113
-        echo $value;
114
-        return $nextPromise;
115
-    })
116
-    ->then(function ($value) {
117
-        echo $value;
118
-    });
119
-
120
-// Triggers the first callback and outputs "A"
121
-$promise->resolve('A');
122
-// Triggers the second callback and outputs "B"
123
-$nextPromise->resolve('B');
124
-```
125
-
126
-## Promise rejection
127
-
128
-When a promise is rejected, the `$onRejected` callbacks are invoked with the
129
-rejection reason.
130
-
131
-```php
132
-use GuzzleHttp\Promise\Promise;
133
-
134
-$promise = new Promise();
135
-$promise->then(null, function ($reason) {
136
-    echo $reason;
137
-});
138
-
139
-$promise->reject('Error!');
140
-// Outputs "Error!"
141
-```
142
-
143
-## Rejection forwarding
144
-
145
-If an exception is thrown in an `$onRejected` callback, subsequent
146
-`$onRejected` callbacks are invoked with the thrown exception as the reason.
147
-
148
-```php
149
-use GuzzleHttp\Promise\Promise;
150
-
151
-$promise = new Promise();
152
-$promise->then(null, function ($reason) {
153
-    throw new Exception($reason);
154
-})->then(null, function ($reason) {
155
-    assert($reason->getMessage() === 'Error!');
156
-});
157
-
158
-$promise->reject('Error!');
159
-```
160
-
161
-You can also forward a rejection down the promise chain by returning a
162
-`GuzzleHttp\Promise\RejectedPromise` in either an `$onFulfilled` or
163
-`$onRejected` callback.
164
-
165
-```php
166
-use GuzzleHttp\Promise\Promise;
167
-use GuzzleHttp\Promise\RejectedPromise;
168
-
169
-$promise = new Promise();
170
-$promise->then(null, function ($reason) {
171
-    return new RejectedPromise($reason);
172
-})->then(null, function ($reason) {
173
-    assert($reason === 'Error!');
174
-});
175
-
176
-$promise->reject('Error!');
177
-```
178
-
179
-If an exception is not thrown in a `$onRejected` callback and the callback
180
-does not return a rejected promise, downstream `$onFulfilled` callbacks are
181
-invoked using the value returned from the `$onRejected` callback.
182
-
183
-```php
184
-use GuzzleHttp\Promise\Promise;
185
-
186
-$promise = new Promise();
187
-$promise
188
-    ->then(null, function ($reason) {
189
-        return "It's ok";
190
-    })
191
-    ->then(function ($value) {
192
-        assert($value === "It's ok");
193
-    });
194
-
195
-$promise->reject('Error!');
196
-```
197
-
198
-# Synchronous wait
199
-
200
-You can synchronously force promises to complete using a promise's `wait`
201
-method. When creating a promise, you can provide a wait function that is used
202
-to synchronously force a promise to complete. When a wait function is invoked
203
-it is expected to deliver a value to the promise or reject the promise. If the
204
-wait function does not deliver a value, then an exception is thrown. The wait
205
-function provided to a promise constructor is invoked when the `wait` function
206
-of the promise is called.
207
-
208
-```php
209
-$promise = new Promise(function () use (&$promise) {
210
-    $promise->resolve('foo');
211
-});
212
-
213
-// Calling wait will return the value of the promise.
214
-echo $promise->wait(); // outputs "foo"
215
-```
216
-
217
-If an exception is encountered while invoking the wait function of a promise,
218
-the promise is rejected with the exception and the exception is thrown.
219
-
220
-```php
221
-$promise = new Promise(function () use (&$promise) {
222
-    throw new Exception('foo');
223
-});
224
-
225
-$promise->wait(); // throws the exception.
226
-```
227
-
228
-Calling `wait` on a promise that has been fulfilled will not trigger the wait
229
-function. It will simply return the previously resolved value.
230
-
231
-```php
232
-$promise = new Promise(function () { die('this is not called!'); });
233
-$promise->resolve('foo');
234
-echo $promise->wait(); // outputs "foo"
235
-```
236
-
237
-Calling `wait` on a promise that has been rejected will throw an exception. If
238
-the rejection reason is an instance of `\Exception` the reason is thrown.
239
-Otherwise, a `GuzzleHttp\Promise\RejectionException` is thrown and the reason
240
-can be obtained by calling the `getReason` method of the exception.
241
-
242
-```php
243
-$promise = new Promise();
244
-$promise->reject('foo');
245
-$promise->wait();
246
-```
247
-
248
-> PHP Fatal error:  Uncaught exception 'GuzzleHttp\Promise\RejectionException' with message 'The promise was rejected with value: foo'
249
-
250
-
251
-## Unwrapping a promise
252
-
253
-When synchronously waiting on a promise, you are joining the state of the
254
-promise into the current state of execution (i.e., return the value of the
255
-promise if it was fulfilled or throw an exception if it was rejected). This is
256
-called "unwrapping" the promise. Waiting on a promise will by default unwrap
257
-the promise state.
258
-
259
-You can force a promise to resolve and *not* unwrap the state of the promise
260
-by passing `false` to the first argument of the `wait` function:
261
-
262
-```php
263
-$promise = new Promise();
264
-$promise->reject('foo');
265
-// This will not throw an exception. It simply ensures the promise has
266
-// been resolved.
267
-$promise->wait(false);
268
-```
269
-
270
-When unwrapping a promise, the resolved value of the promise will be waited
271
-upon until the unwrapped value is not a promise. This means that if you resolve
272
-promise A with a promise B and unwrap promise A, the value returned by the
273
-wait function will be the value delivered to promise B.
274
-
275
-**Note**: when you do not unwrap the promise, no value is returned.
276
-
277
-
278
-# Cancellation
279
-
280
-You can cancel a promise that has not yet been fulfilled using the `cancel()`
281
-method of a promise. When creating a promise you can provide an optional
282
-cancel function that when invoked cancels the action of computing a resolution
283
-of the promise.
284
-
285
-
286
-# API
287
-
288
-
289
-## Promise
290
-
291
-When creating a promise object, you can provide an optional `$waitFn` and
292
-`$cancelFn`. `$waitFn` is a function that is invoked with no arguments and is
293
-expected to resolve the promise. `$cancelFn` is a function with no arguments
294
-that is expected to cancel the computation of a promise. It is invoked when the
295
-`cancel()` method of a promise is called.
296
-
297
-```php
298
-use GuzzleHttp\Promise\Promise;
299
-
300
-$promise = new Promise(
301
-    function () use (&$promise) {
302
-        $promise->resolve('waited');
303
-    },
304
-    function () {
305
-        // do something that will cancel the promise computation (e.g., close
306
-        // a socket, cancel a database query, etc...)
307
-    }
308
-);
309
-
310
-assert('waited' === $promise->wait());
311
-```
312
-
313
-A promise has the following methods:
314
-
315
-- `then(callable $onFulfilled, callable $onRejected) : PromiseInterface`
316
-  
317
-  Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.
318
-
319
-- `otherwise(callable $onRejected) : PromiseInterface`
320
-  
321
-  Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
322
-
323
-- `wait($unwrap = true) : mixed`
324
-
325
-  Synchronously waits on the promise to complete.
326
-  
327
-  `$unwrap` controls whether or not the value of the promise is returned for a
328
-  fulfilled promise or if an exception is thrown if the promise is rejected.
329
-  This is set to `true` by default.
330
-
331
-- `cancel()`
332
-
333
-  Attempts to cancel the promise if possible. The promise being cancelled and
334
-  the parent most ancestor that has not yet been resolved will also be
335
-  cancelled. Any promises waiting on the cancelled promise to resolve will also
336
-  be cancelled.
337
-
338
-- `getState() : string`
339
-
340
-  Returns the state of the promise. One of `pending`, `fulfilled`, or
341
-  `rejected`.
342
-
343
-- `resolve($value)`
344
-
345
-  Fulfills the promise with the given `$value`.
346
-
347
-- `reject($reason)`
348
-
349
-  Rejects the promise with the given `$reason`.
350
-
351
-
352
-## FulfilledPromise
353
-
354
-A fulfilled promise can be created to represent a promise that has been
355
-fulfilled.
356
-
357
-```php
358
-use GuzzleHttp\Promise\FulfilledPromise;
359
-
360
-$promise = new FulfilledPromise('value');
361
-
362
-// Fulfilled callbacks are immediately invoked.
363
-$promise->then(function ($value) {
364
-    echo $value;
365
-});
366
-```
367
-
368
-
369
-## RejectedPromise
370
-
371
-A rejected promise can be created to represent a promise that has been
372
-rejected.
373
-
374
-```php
375
-use GuzzleHttp\Promise\RejectedPromise;
376
-
377
-$promise = new RejectedPromise('Error');
378
-
379
-// Rejected callbacks are immediately invoked.
380
-$promise->then(null, function ($reason) {
381
-    echo $reason;
382
-});
383
-```
384
-
385
-
386
-# Promise interop
387
-
388
-This library works with foreign promises that have a `then` method. This means
389
-you can use Guzzle promises with [React promises](https://github.com/reactphp/promise)
390
-for example. When a foreign promise is returned inside of a then method
391
-callback, promise resolution will occur recursively.
392
-
393
-```php
394
-// Create a React promise
395
-$deferred = new React\Promise\Deferred();
396
-$reactPromise = $deferred->promise();
397
-
398
-// Create a Guzzle promise that is fulfilled with a React promise.
399
-$guzzlePromise = new GuzzleHttp\Promise\Promise();
400
-$guzzlePromise->then(function ($value) use ($reactPromise) {
401
-    // Do something something with the value...
402
-    // Return the React promise
403
-    return $reactPromise;
404
-});
405
-```
406
-
407
-Please note that wait and cancel chaining is no longer possible when forwarding
408
-a foreign promise. You will need to wrap a third-party promise with a Guzzle
409
-promise in order to utilize wait and cancel functions with foreign promises.
410
-
411
-
412
-## Event Loop Integration
413
-
414
-In order to keep the stack size constant, Guzzle promises are resolved
415
-asynchronously using a task queue. When waiting on promises synchronously, the
416
-task queue will be automatically run to ensure that the blocking promise and
417
-any forwarded promises are resolved. When using promises asynchronously in an
418
-event loop, you will need to run the task queue on each tick of the loop. If
419
-you do not run the task queue, then promises will not be resolved.
420
-
421
-You can run the task queue using the `run()` method of the global task queue
422
-instance.
423
-
424
-```php
425
-// Get the global task queue
426
-$queue = GuzzleHttp\Promise\Utils::queue();
427
-$queue->run();
428
-```
429
-
430
-For example, you could use Guzzle promises with React using a periodic timer:
431
-
432
-```php
433
-$loop = React\EventLoop\Factory::create();
434
-$loop->addPeriodicTimer(0, [$queue, 'run']);
435
-```
436
-
437
-*TODO*: Perhaps adding a `futureTick()` on each tick would be faster?
438
-
439
-
440
-# Implementation notes
441
-
442
-
443
-## Promise resolution and chaining is handled iteratively
444
-
445
-By shuffling pending handlers from one owner to another, promises are
446
-resolved iteratively, allowing for "infinite" then chaining.
447
-
448
-```php
449
-<?php
450
-require 'vendor/autoload.php';
451
-
452
-use GuzzleHttp\Promise\Promise;
453
-
454
-$parent = new Promise();
455
-$p = $parent;
456
-
457
-for ($i = 0; $i < 1000; $i++) {
458
-    $p = $p->then(function ($v) {
459
-        // The stack size remains constant (a good thing)
460
-        echo xdebug_get_stack_depth() . ', ';
461
-        return $v + 1;
462
-    });
463
-}
464
-
465
-$parent->resolve(0);
466
-var_dump($p->wait()); // int(1000)
467
-
468
-```
469
-
470
-When a promise is fulfilled or rejected with a non-promise value, the promise
471
-then takes ownership of the handlers of each child promise and delivers values
472
-down the chain without using recursion.
473
-
474
-When a promise is resolved with another promise, the original promise transfers
475
-all of its pending handlers to the new promise. When the new promise is
476
-eventually resolved, all of the pending handlers are delivered the forwarded
477
-value.
478
-
479
-
480
-## A promise is the deferred.
481
-
482
-Some promise libraries implement promises using a deferred object to represent
483
-a computation and a promise object to represent the delivery of the result of
484
-the computation. This is a nice separation of computation and delivery because
485
-consumers of the promise cannot modify the value that will be eventually
486
-delivered.
487
-
488
-One side effect of being able to implement promise resolution and chaining
489
-iteratively is that you need to be able for one promise to reach into the state
490
-of another promise to shuffle around ownership of handlers. In order to achieve
491
-this without making the handlers of a promise publicly mutable, a promise is
492
-also the deferred value, allowing promises of the same parent class to reach
493
-into and modify the private properties of promises of the same type. While this
494
-does allow consumers of the value to modify the resolution or rejection of the
495
-deferred, it is a small price to pay for keeping the stack size constant.
496
-
497
-```php
498
-$promise = new Promise();
499
-$promise->then(function ($value) { echo $value; });
500
-// The promise is the deferred value, so you can deliver a value to it.
501
-$promise->resolve('foo');
502
-// prints "foo"
503
-```
504
-
505
-
506
-## Upgrading from Function API
507
-
508
-A static API was first introduced in 1.4.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience:
509
-
510
-| Original Function | Replacement Method |
511
-|----------------|----------------|
512
-| `queue` | `Utils::queue` |
513
-| `task` | `Utils::task` |
514
-| `promise_for` | `Create::promiseFor` |
515
-| `rejection_for` | `Create::rejectionFor` |
516
-| `exception_for` | `Create::exceptionFor` |
517
-| `iter_for` | `Create::iterFor` |
518
-| `inspect` | `Utils::inspect` |
519
-| `inspect_all` | `Utils::inspectAll` |
520
-| `unwrap` | `Utils::unwrap` |
521
-| `all` | `Utils::all` |
522
-| `some` | `Utils::some` |
523
-| `any` | `Utils::any` |
524
-| `settle` | `Utils::settle` |
525
-| `each` | `Each::of` |
526
-| `each_limit` | `Each::ofLimit` |
527
-| `each_limit_all` | `Each::ofLimitAll` |
528
-| `!is_fulfilled` | `Is::pending` |
529
-| `is_fulfilled` | `Is::fulfilled` |
530
-| `is_rejected` | `Is::rejected` |
531
-| `is_settled` | `Is::settled` |
532
-| `coroutine` | `Coroutine::of` |
Browse code

Added README.md appinfo/info.xml appinfo/signature.json lib/Controller/AuthorApiController.php and the providers directory

DoubleBastionAdmin authored on 20/08/2022 16:33:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,532 @@
1
+# Guzzle Promises
2
+
3
+[Promises/A+](https://promisesaplus.com/) implementation that handles promise
4
+chaining and resolution iteratively, allowing for "infinite" promise chaining
5
+while keeping the stack size constant. Read [this blog post](https://blog.domenic.me/youre-missing-the-point-of-promises/)
6
+for a general introduction to promises.
7
+
8
+- [Features](#features)
9
+- [Quick start](#quick-start)
10
+- [Synchronous wait](#synchronous-wait)
11
+- [Cancellation](#cancellation)
12
+- [API](#api)
13
+  - [Promise](#promise)
14
+  - [FulfilledPromise](#fulfilledpromise)
15
+  - [RejectedPromise](#rejectedpromise)
16
+- [Promise interop](#promise-interop)
17
+- [Implementation notes](#implementation-notes)
18
+
19
+
20
+# Features
21
+
22
+- [Promises/A+](https://promisesaplus.com/) implementation.
23
+- Promise resolution and chaining is handled iteratively, allowing for
24
+  "infinite" promise chaining.
25
+- Promises have a synchronous `wait` method.
26
+- Promises can be cancelled.
27
+- Works with any object that has a `then` function.
28
+- C# style async/await coroutine promises using
29
+  `GuzzleHttp\Promise\Coroutine::of()`.
30
+
31
+
32
+# Quick start
33
+
34
+A *promise* represents the eventual result of an asynchronous operation. The
35
+primary way of interacting with a promise is through its `then` method, which
36
+registers callbacks to receive either a promise's eventual value or the reason
37
+why the promise cannot be fulfilled.
38
+
39
+
40
+## Callbacks
41
+
42
+Callbacks are registered with the `then` method by providing an optional 
43
+`$onFulfilled` followed by an optional `$onRejected` function.
44
+
45
+
46
+```php
47
+use GuzzleHttp\Promise\Promise;
48
+
49
+$promise = new Promise();
50
+$promise->then(
51
+    // $onFulfilled
52
+    function ($value) {
53
+        echo 'The promise was fulfilled.';
54
+    },
55
+    // $onRejected
56
+    function ($reason) {
57
+        echo 'The promise was rejected.';
58
+    }
59
+);
60
+```
61
+
62
+*Resolving* a promise means that you either fulfill a promise with a *value* or
63
+reject a promise with a *reason*. Resolving a promises triggers callbacks
64
+registered with the promises's `then` method. These callbacks are triggered
65
+only once and in the order in which they were added.
66
+
67
+
68
+## Resolving a promise
69
+
70
+Promises are fulfilled using the `resolve($value)` method. Resolving a promise
71
+with any value other than a `GuzzleHttp\Promise\RejectedPromise` will trigger
72
+all of the onFulfilled callbacks (resolving a promise with a rejected promise
73
+will reject the promise and trigger the `$onRejected` callbacks).
74
+
75
+```php
76
+use GuzzleHttp\Promise\Promise;
77
+
78
+$promise = new Promise();
79
+$promise
80
+    ->then(function ($value) {
81
+        // Return a value and don't break the chain
82
+        return "Hello, " . $value;
83
+    })
84
+    // This then is executed after the first then and receives the value
85
+    // returned from the first then.
86
+    ->then(function ($value) {
87
+        echo $value;
88
+    });
89
+
90
+// Resolving the promise triggers the $onFulfilled callbacks and outputs
91
+// "Hello, reader."
92
+$promise->resolve('reader.');
93
+```
94
+
95
+
96
+## Promise forwarding
97
+
98
+Promises can be chained one after the other. Each then in the chain is a new
99
+promise. The return value of a promise is what's forwarded to the next
100
+promise in the chain. Returning a promise in a `then` callback will cause the
101
+subsequent promises in the chain to only be fulfilled when the returned promise
102
+has been fulfilled. The next promise in the chain will be invoked with the
103
+resolved value of the promise.
104
+
105
+```php
106
+use GuzzleHttp\Promise\Promise;
107
+
108
+$promise = new Promise();
109
+$nextPromise = new Promise();
110
+
111
+$promise
112
+    ->then(function ($value) use ($nextPromise) {
113
+        echo $value;
114
+        return $nextPromise;
115
+    })
116
+    ->then(function ($value) {
117
+        echo $value;
118
+    });
119
+
120
+// Triggers the first callback and outputs "A"
121
+$promise->resolve('A');
122
+// Triggers the second callback and outputs "B"
123
+$nextPromise->resolve('B');
124
+```
125
+
126
+## Promise rejection
127
+
128
+When a promise is rejected, the `$onRejected` callbacks are invoked with the
129
+rejection reason.
130
+
131
+```php
132
+use GuzzleHttp\Promise\Promise;
133
+
134
+$promise = new Promise();
135
+$promise->then(null, function ($reason) {
136
+    echo $reason;
137
+});
138
+
139
+$promise->reject('Error!');
140
+// Outputs "Error!"
141
+```
142
+
143
+## Rejection forwarding
144
+
145
+If an exception is thrown in an `$onRejected` callback, subsequent
146
+`$onRejected` callbacks are invoked with the thrown exception as the reason.
147
+
148
+```php
149
+use GuzzleHttp\Promise\Promise;
150
+
151
+$promise = new Promise();
152
+$promise->then(null, function ($reason) {
153
+    throw new Exception($reason);
154
+})->then(null, function ($reason) {
155
+    assert($reason->getMessage() === 'Error!');
156
+});
157
+
158
+$promise->reject('Error!');
159
+```
160
+
161
+You can also forward a rejection down the promise chain by returning a
162
+`GuzzleHttp\Promise\RejectedPromise` in either an `$onFulfilled` or
163
+`$onRejected` callback.
164
+
165
+```php
166
+use GuzzleHttp\Promise\Promise;
167
+use GuzzleHttp\Promise\RejectedPromise;
168
+
169
+$promise = new Promise();
170
+$promise->then(null, function ($reason) {
171
+    return new RejectedPromise($reason);
172
+})->then(null, function ($reason) {
173
+    assert($reason === 'Error!');
174
+});
175
+
176
+$promise->reject('Error!');
177
+```
178
+
179
+If an exception is not thrown in a `$onRejected` callback and the callback
180
+does not return a rejected promise, downstream `$onFulfilled` callbacks are
181
+invoked using the value returned from the `$onRejected` callback.
182
+
183
+```php
184
+use GuzzleHttp\Promise\Promise;
185
+
186
+$promise = new Promise();
187
+$promise
188
+    ->then(null, function ($reason) {
189
+        return "It's ok";
190
+    })
191
+    ->then(function ($value) {
192
+        assert($value === "It's ok");
193
+    });
194
+
195
+$promise->reject('Error!');
196
+```
197
+
198
+# Synchronous wait
199
+
200
+You can synchronously force promises to complete using a promise's `wait`
201
+method. When creating a promise, you can provide a wait function that is used
202
+to synchronously force a promise to complete. When a wait function is invoked
203
+it is expected to deliver a value to the promise or reject the promise. If the
204
+wait function does not deliver a value, then an exception is thrown. The wait
205
+function provided to a promise constructor is invoked when the `wait` function
206
+of the promise is called.
207
+
208
+```php
209
+$promise = new Promise(function () use (&$promise) {
210
+    $promise->resolve('foo');
211
+});
212
+
213
+// Calling wait will return the value of the promise.
214
+echo $promise->wait(); // outputs "foo"
215
+```
216
+
217
+If an exception is encountered while invoking the wait function of a promise,
218
+the promise is rejected with the exception and the exception is thrown.
219
+
220
+```php
221
+$promise = new Promise(function () use (&$promise) {
222
+    throw new Exception('foo');
223
+});
224
+
225
+$promise->wait(); // throws the exception.
226
+```
227
+
228
+Calling `wait` on a promise that has been fulfilled will not trigger the wait
229
+function. It will simply return the previously resolved value.
230
+
231
+```php
232
+$promise = new Promise(function () { die('this is not called!'); });
233
+$promise->resolve('foo');
234
+echo $promise->wait(); // outputs "foo"
235
+```
236
+
237
+Calling `wait` on a promise that has been rejected will throw an exception. If
238
+the rejection reason is an instance of `\Exception` the reason is thrown.
239
+Otherwise, a `GuzzleHttp\Promise\RejectionException` is thrown and the reason
240
+can be obtained by calling the `getReason` method of the exception.
241
+
242
+```php
243
+$promise = new Promise();
244
+$promise->reject('foo');
245
+$promise->wait();
246
+```
247
+
248
+> PHP Fatal error:  Uncaught exception 'GuzzleHttp\Promise\RejectionException' with message 'The promise was rejected with value: foo'
249
+
250
+
251
+## Unwrapping a promise
252
+
253
+When synchronously waiting on a promise, you are joining the state of the
254
+promise into the current state of execution (i.e., return the value of the
255
+promise if it was fulfilled or throw an exception if it was rejected). This is
256
+called "unwrapping" the promise. Waiting on a promise will by default unwrap
257
+the promise state.
258
+
259
+You can force a promise to resolve and *not* unwrap the state of the promise
260
+by passing `false` to the first argument of the `wait` function:
261
+
262
+```php
263
+$promise = new Promise();
264
+$promise->reject('foo');
265
+// This will not throw an exception. It simply ensures the promise has
266
+// been resolved.
267
+$promise->wait(false);
268
+```
269
+
270
+When unwrapping a promise, the resolved value of the promise will be waited
271
+upon until the unwrapped value is not a promise. This means that if you resolve
272
+promise A with a promise B and unwrap promise A, the value returned by the
273
+wait function will be the value delivered to promise B.
274
+
275
+**Note**: when you do not unwrap the promise, no value is returned.
276
+
277
+
278
+# Cancellation
279
+
280
+You can cancel a promise that has not yet been fulfilled using the `cancel()`
281
+method of a promise. When creating a promise you can provide an optional
282
+cancel function that when invoked cancels the action of computing a resolution
283
+of the promise.
284
+
285
+
286
+# API
287
+
288
+
289
+## Promise
290
+
291
+When creating a promise object, you can provide an optional `$waitFn` and
292
+`$cancelFn`. `$waitFn` is a function that is invoked with no arguments and is
293
+expected to resolve the promise. `$cancelFn` is a function with no arguments
294
+that is expected to cancel the computation of a promise. It is invoked when the
295
+`cancel()` method of a promise is called.
296
+
297
+```php
298
+use GuzzleHttp\Promise\Promise;
299
+
300
+$promise = new Promise(
301
+    function () use (&$promise) {
302
+        $promise->resolve('waited');
303
+    },
304
+    function () {
305
+        // do something that will cancel the promise computation (e.g., close
306
+        // a socket, cancel a database query, etc...)
307
+    }
308
+);
309
+
310
+assert('waited' === $promise->wait());
311
+```
312
+
313
+A promise has the following methods:
314
+
315
+- `then(callable $onFulfilled, callable $onRejected) : PromiseInterface`
316
+  
317
+  Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.
318
+
319
+- `otherwise(callable $onRejected) : PromiseInterface`
320
+  
321
+  Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
322
+
323
+- `wait($unwrap = true) : mixed`
324
+
325
+  Synchronously waits on the promise to complete.
326
+  
327
+  `$unwrap` controls whether or not the value of the promise is returned for a
328
+  fulfilled promise or if an exception is thrown if the promise is rejected.
329
+  This is set to `true` by default.
330
+
331
+- `cancel()`
332
+
333
+  Attempts to cancel the promise if possible. The promise being cancelled and
334
+  the parent most ancestor that has not yet been resolved will also be
335
+  cancelled. Any promises waiting on the cancelled promise to resolve will also
336
+  be cancelled.
337
+
338
+- `getState() : string`
339
+
340
+  Returns the state of the promise. One of `pending`, `fulfilled`, or
341
+  `rejected`.
342
+
343
+- `resolve($value)`
344
+
345
+  Fulfills the promise with the given `$value`.
346
+
347
+- `reject($reason)`
348
+
349
+  Rejects the promise with the given `$reason`.
350
+
351
+
352
+## FulfilledPromise
353
+
354
+A fulfilled promise can be created to represent a promise that has been
355
+fulfilled.
356
+
357
+```php
358
+use GuzzleHttp\Promise\FulfilledPromise;
359
+
360
+$promise = new FulfilledPromise('value');
361
+
362
+// Fulfilled callbacks are immediately invoked.
363
+$promise->then(function ($value) {
364
+    echo $value;
365
+});
366
+```
367
+
368
+
369
+## RejectedPromise
370
+
371
+A rejected promise can be created to represent a promise that has been
372
+rejected.
373
+
374
+```php
375
+use GuzzleHttp\Promise\RejectedPromise;
376
+
377
+$promise = new RejectedPromise('Error');
378
+
379
+// Rejected callbacks are immediately invoked.
380
+$promise->then(null, function ($reason) {
381
+    echo $reason;
382
+});
383
+```
384
+
385
+
386
+# Promise interop
387
+
388
+This library works with foreign promises that have a `then` method. This means
389
+you can use Guzzle promises with [React promises](https://github.com/reactphp/promise)
390
+for example. When a foreign promise is returned inside of a then method
391
+callback, promise resolution will occur recursively.
392
+
393
+```php
394
+// Create a React promise
395
+$deferred = new React\Promise\Deferred();
396
+$reactPromise = $deferred->promise();
397
+
398
+// Create a Guzzle promise that is fulfilled with a React promise.
399
+$guzzlePromise = new GuzzleHttp\Promise\Promise();
400
+$guzzlePromise->then(function ($value) use ($reactPromise) {
401
+    // Do something something with the value...
402
+    // Return the React promise
403
+    return $reactPromise;
404
+});
405
+```
406
+
407
+Please note that wait and cancel chaining is no longer possible when forwarding
408
+a foreign promise. You will need to wrap a third-party promise with a Guzzle
409
+promise in order to utilize wait and cancel functions with foreign promises.
410
+
411
+
412
+## Event Loop Integration
413
+
414
+In order to keep the stack size constant, Guzzle promises are resolved
415
+asynchronously using a task queue. When waiting on promises synchronously, the
416
+task queue will be automatically run to ensure that the blocking promise and
417
+any forwarded promises are resolved. When using promises asynchronously in an
418
+event loop, you will need to run the task queue on each tick of the loop. If
419
+you do not run the task queue, then promises will not be resolved.
420
+
421
+You can run the task queue using the `run()` method of the global task queue
422
+instance.
423
+
424
+```php
425
+// Get the global task queue
426
+$queue = GuzzleHttp\Promise\Utils::queue();
427
+$queue->run();
428
+```
429
+
430
+For example, you could use Guzzle promises with React using a periodic timer:
431
+
432
+```php
433
+$loop = React\EventLoop\Factory::create();
434
+$loop->addPeriodicTimer(0, [$queue, 'run']);
435
+```
436
+
437
+*TODO*: Perhaps adding a `futureTick()` on each tick would be faster?
438
+
439
+
440
+# Implementation notes
441
+
442
+
443
+## Promise resolution and chaining is handled iteratively
444
+
445
+By shuffling pending handlers from one owner to another, promises are
446
+resolved iteratively, allowing for "infinite" then chaining.
447
+
448
+```php
449
+<?php
450
+require 'vendor/autoload.php';
451
+
452
+use GuzzleHttp\Promise\Promise;
453
+
454
+$parent = new Promise();
455
+$p = $parent;
456
+
457
+for ($i = 0; $i < 1000; $i++) {
458
+    $p = $p->then(function ($v) {
459
+        // The stack size remains constant (a good thing)
460
+        echo xdebug_get_stack_depth() . ', ';
461
+        return $v + 1;
462
+    });
463
+}
464
+
465
+$parent->resolve(0);
466
+var_dump($p->wait()); // int(1000)
467
+
468
+```
469
+
470
+When a promise is fulfilled or rejected with a non-promise value, the promise
471
+then takes ownership of the handlers of each child promise and delivers values
472
+down the chain without using recursion.
473
+
474
+When a promise is resolved with another promise, the original promise transfers
475
+all of its pending handlers to the new promise. When the new promise is
476
+eventually resolved, all of the pending handlers are delivered the forwarded
477
+value.
478
+
479
+
480
+## A promise is the deferred.
481
+
482
+Some promise libraries implement promises using a deferred object to represent
483
+a computation and a promise object to represent the delivery of the result of
484
+the computation. This is a nice separation of computation and delivery because
485
+consumers of the promise cannot modify the value that will be eventually
486
+delivered.
487
+
488
+One side effect of being able to implement promise resolution and chaining
489
+iteratively is that you need to be able for one promise to reach into the state
490
+of another promise to shuffle around ownership of handlers. In order to achieve
491
+this without making the handlers of a promise publicly mutable, a promise is
492
+also the deferred value, allowing promises of the same parent class to reach
493
+into and modify the private properties of promises of the same type. While this
494
+does allow consumers of the value to modify the resolution or rejection of the
495
+deferred, it is a small price to pay for keeping the stack size constant.
496
+
497
+```php
498
+$promise = new Promise();
499
+$promise->then(function ($value) { echo $value; });
500
+// The promise is the deferred value, so you can deliver a value to it.
501
+$promise->resolve('foo');
502
+// prints "foo"
503
+```
504
+
505
+
506
+## Upgrading from Function API
507
+
508
+A static API was first introduced in 1.4.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience:
509
+
510
+| Original Function | Replacement Method |
511
+|----------------|----------------|
512
+| `queue` | `Utils::queue` |
513
+| `task` | `Utils::task` |
514
+| `promise_for` | `Create::promiseFor` |
515
+| `rejection_for` | `Create::rejectionFor` |
516
+| `exception_for` | `Create::exceptionFor` |
517
+| `iter_for` | `Create::iterFor` |
518
+| `inspect` | `Utils::inspect` |
519
+| `inspect_all` | `Utils::inspectAll` |
520
+| `unwrap` | `Utils::unwrap` |
521
+| `all` | `Utils::all` |
522
+| `some` | `Utils::some` |
523
+| `any` | `Utils::any` |
524
+| `settle` | `Utils::settle` |
525
+| `each` | `Each::of` |
526
+| `each_limit` | `Each::ofLimit` |
527
+| `each_limit_all` | `Each::ofLimitAll` |
528
+| `!is_fulfilled` | `Is::pending` |
529
+| `is_fulfilled` | `Is::fulfilled` |
530
+| `is_rejected` | `Is::rejected` |
531
+| `is_settled` | `Is::settled` |
532
+| `coroutine` | `Coroutine::of` |