mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 12:56:05 +03:00
Fix coroutine executor when using with promise
This commit is contained in:
parent
0b4b1485e0
commit
08d9493b2c
@ -293,13 +293,17 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation
|
|||||||
$strand->stack[$strand->depth++] = $strand->current;
|
$strand->stack[$strand->depth++] = $strand->current;
|
||||||
$strand->current = $value;
|
$strand->current = $value;
|
||||||
goto START;
|
goto START;
|
||||||
} elseif ($this->promiseAdapter->isThenable($value)) {
|
} elseif ($this->isPromise($value)) {
|
||||||
// !!! increment pending before calling ->then() as it may invoke the callback right away
|
// !!! increment pending before calling ->then() as it may invoke the callback right away
|
||||||
++$this->pending;
|
++$this->pending;
|
||||||
|
|
||||||
|
if (! $value instanceof Promise) {
|
||||||
|
$value = $this->promiseAdapter->convertThenable($value);
|
||||||
|
}
|
||||||
|
|
||||||
$this->promiseAdapter
|
$this->promiseAdapter
|
||||||
->convertThenable($value)
|
|
||||||
->then(
|
->then(
|
||||||
|
$value,
|
||||||
function ($value) use ($strand) {
|
function ($value) use ($strand) {
|
||||||
$strand->success = true;
|
$strand->success = true;
|
||||||
$strand->value = $value;
|
$strand->value = $value;
|
||||||
@ -478,7 +482,7 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation
|
|||||||
private function completeValueFast(CoroutineContext $ctx, Type $type, $value, array $path, &$returnValue) : bool
|
private function completeValueFast(CoroutineContext $ctx, Type $type, $value, array $path, &$returnValue) : bool
|
||||||
{
|
{
|
||||||
// special handling of Throwable inherited from JS reference implementation, but makes no sense in this PHP
|
// special handling of Throwable inherited from JS reference implementation, but makes no sense in this PHP
|
||||||
if ($this->promiseAdapter->isThenable($value) || $value instanceof Throwable) {
|
if ($this->isPromise($value) || $value instanceof Throwable) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +578,7 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation
|
|||||||
|
|
||||||
// !!! $value might be promise, yield to resolve
|
// !!! $value might be promise, yield to resolve
|
||||||
try {
|
try {
|
||||||
if ($this->promiseAdapter->isThenable($value)) {
|
if ($this->isPromise($value)) {
|
||||||
$value = yield $value;
|
$value = yield $value;
|
||||||
}
|
}
|
||||||
} catch (Throwable $reason) {
|
} catch (Throwable $reason) {
|
||||||
@ -931,4 +935,14 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation
|
|||||||
|
|
||||||
return $selectedType;
|
return $selectedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $value
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isPromise($value)
|
||||||
|
{
|
||||||
|
return $value instanceof Promise || $this->promiseAdapter->isThenable($value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,6 @@ class GraphQLTest extends TestCase
|
|||||||
|
|
||||||
$promise = GraphQL::promiseToExecute($promiseAdapter, $schema, '{ sayHi(name: "John") }');
|
$promise = GraphQL::promiseToExecute($promiseAdapter, $schema, '{ sayHi(name: "John") }');
|
||||||
$result = $promiseAdapter->wait($promise);
|
$result = $promiseAdapter->wait($promise);
|
||||||
$this->assertSame(['data' => ['sayHi' => 'Hi John!']], $result->toArray());
|
self::assertSame(['data' => ['sayHi' => 'Hi John!']], $result->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user