mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Fix Promise::all() to handle mixed values and promises
The graphql-php executor passes both promises and plain values to the PromiseAdapter::all() method. Updated SwoolePromise::all() to properly handle plain values by storing them directly without attempting to call ->then() on them. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
762be367e1
commit
a70d67810e
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user