functions.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. declare(strict_types=1);
  3. namespace Sabre\Event\Promise;
  4. use Sabre\Event\Promise;
  5. /**
  6. * This file contains a set of functions that are useful for dealing with the
  7. * Promise object.
  8. *
  9. * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
  10. * @author Evert Pot (http://evertpot.com/)
  11. * @license http://sabre.io/license/ Modified BSD License
  12. */
  13. /**
  14. * This function takes an array of Promises, and returns a Promise that
  15. * resolves when all the given arguments have resolved.
  16. *
  17. * The returned Promise will resolve with a value that's an array of all the
  18. * values the given promises have been resolved with.
  19. *
  20. * This array will be in the exact same order as the array of input promises.
  21. *
  22. * If any of the given Promises fails, the returned promise will immediately
  23. * fail with the first Promise that fails, and its reason.
  24. *
  25. * @param Promise[] $promises
  26. */
  27. function all(array $promises): Promise
  28. {
  29. return new Promise(function ($success, $fail) use ($promises) {
  30. if (empty($promises)) {
  31. $success([]);
  32. return;
  33. }
  34. $successCount = 0;
  35. $completeResult = [];
  36. foreach ($promises as $promiseIndex => $subPromise) {
  37. $subPromise->then(
  38. function ($result) use ($promiseIndex, &$completeResult, &$successCount, $success, $promises) {
  39. $completeResult[$promiseIndex] = $result;
  40. ++$successCount;
  41. if ($successCount === count($promises)) {
  42. $success($completeResult);
  43. }
  44. return $result;
  45. }
  46. )->otherwise(
  47. function ($reason) use ($fail) {
  48. $fail($reason);
  49. }
  50. );
  51. }
  52. });
  53. }
  54. /**
  55. * The race function returns a promise that resolves or rejects as soon as
  56. * one of the promises in the argument resolves or rejects.
  57. *
  58. * The returned promise will resolve or reject with the value or reason of
  59. * that first promise.
  60. *
  61. * @param Promise[] $promises
  62. */
  63. function race(array $promises): Promise
  64. {
  65. return new Promise(function ($success, $fail) use ($promises) {
  66. $alreadyDone = false;
  67. foreach ($promises as $promise) {
  68. $promise->then(
  69. function ($result) use ($success, &$alreadyDone) {
  70. if ($alreadyDone) {
  71. return;
  72. }
  73. $alreadyDone = true;
  74. $success($result);
  75. },
  76. function ($reason) use ($fail, &$alreadyDone) {
  77. if ($alreadyDone) {
  78. return;
  79. }
  80. $alreadyDone = true;
  81. $fail($reason);
  82. }
  83. );
  84. }
  85. });
  86. }
  87. /**
  88. * Returns a Promise that resolves with the given value.
  89. *
  90. * If the value is a promise, the returned promise will attach itself to that
  91. * promise and eventually get the same state as the followed promise.
  92. */
  93. function resolve($value): Promise
  94. {
  95. if ($value instanceof Promise) {
  96. return $value->then();
  97. } else {
  98. $promise = new Promise();
  99. $promise->fulfill($value);
  100. return $promise;
  101. }
  102. }
  103. /**
  104. * Returns a Promise that will reject with the given reason.
  105. */
  106. function reject(\Throwable $reason): Promise
  107. {
  108. $promise = new Promise();
  109. $promise->reject($reason);
  110. return $promise;
  111. }