[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/guzzlehttp/promises/ -> README.md (source)

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


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1