From 3bc952a036c5359ec8d50d151811a12759030e3f Mon Sep 17 00:00:00 2001 From: Mathieu Ledru Date: Thu, 22 Apr 2021 00:05:29 +0200 Subject: [PATCH] :construction: integrate EventLoop->promiseAll --- src/Adapter/Swoole/EventLoop.php | 33 ++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Adapter/Swoole/EventLoop.php b/src/Adapter/Swoole/EventLoop.php index fab6fed..36f5e56 100644 --- a/src/Adapter/Swoole/EventLoop.php +++ b/src/Adapter/Swoole/EventLoop.php @@ -7,7 +7,6 @@ use M6Web\Tornado\Deferred; use M6Web\Tornado\Promise; use Swoole\Coroutine; -use Swoole\Coroutine\WaitGroup; use Swoole\Event; use RuntimeException; use function extension_loaded; @@ -62,13 +61,39 @@ public function async(\Generator $generator): Promise */ public function promiseAll(Promise ...$promises): Promise { - $promise = new YieldPromise(); + $nbPromises = count($promises); + if ($nbPromises === 0) { + return $this->promiseFulfilled([]); + } + + $globalPromise = new YieldPromise(); + $allResults = array_fill(0, $nbPromises, false); + + // To ensure that the last resolved promise resolves the global promise immediately + $waitOnePromise = function (int $index, Promise $promise) use ($globalPromise, &$nbPromises, &$allResults): \Generator { + try { + $allResults[$index] = yield $promise; + } catch (\Throwable $throwable) { + // Prevent to reject the globalPromise twice + if ($nbPromises > 0) { + $nbPromises = -1; + $globalPromise->reject($throwable); + + return; + } + } - foreach ($promises as $p) { + // Last resolved promise resolved globalPromise + if (--$nbPromises === 0) { + $globalPromise->resolve($allResults); + } + }; + foreach ($promises as $index => $promise) { + $this->async($waitOnePromise($index, $promise)); } - return $promise; + return $globalPromise; } /**