diff --git a/src/Appwrite/Promises/Swoole.php b/src/Appwrite/Promises/Swoole.php index 27e30612ef..a1eacb48dc 100644 --- a/src/Appwrite/Promises/Swoole.php +++ b/src/Appwrite/Promises/Swoole.php @@ -28,33 +28,62 @@ class Swoole extends Promise /** * Returns a promise that completes when all passed in promises complete. * - * @param iterable|Swoole[] $promises + * @param iterable $promisesOrValues Array of promises and/or plain values * @return Promise */ - public static function all(iterable $promises): Promise + public static function all(iterable $promisesOrValues): Promise { - return self::create(function (callable $resolve, callable $reject) use ($promises) { - $ticks = count($promises); - + return self::create(function (callable $resolve, callable $reject) use ($promisesOrValues) { $result = []; $error = null; - $channel = new Channel($ticks); + $promiseCount = 0; $key = 0; - foreach ($promises as $promise) { - $promise->then(function ($value) use ($key, &$result, $channel) { - $result[$key] = $value; - $channel->push(true); - return $value; - }, function ($err) use ($channel, &$error) { - $channel->push(true); - if ($error === null) { - $error = $err; - } - }); + // First pass: count promises and store plain values + $promiseKeys = []; + foreach ($promisesOrValues as $promiseOrValue) { + if ($promiseOrValue instanceof Promise) { + $promiseKeys[] = $key; + $promiseCount++; + } else { + $result[$key] = $promiseOrValue; + } $key++; } - while ($ticks--) { + + // If no promises, resolve immediately + if ($promiseCount === 0) { + \ksort($result); + $resolve($result); + return; + } + + $channel = new Channel($promiseCount); + $key = 0; + + foreach ($promisesOrValues as $promiseOrValue) { + if ($promiseOrValue instanceof Promise) { + $currentKey = $key; + $promiseOrValue->then( + function ($value) use ($currentKey, &$result, $channel) { + $result[$currentKey] = $value; + $channel->push(true); + return $value; + }, + function ($err) use ($channel, &$error) { + $channel->push(true); + if ($error === null) { + $error = $err; + } + } + ); + } + $key++; + } + + // Wait for all promises + $remaining = $promiseCount; + while ($remaining-- > 0) { $channel->pop(); } $channel->close();