diff --git a/src/Symfony/Component/HttpClient/Response/HttplugPromise.php b/src/Symfony/Component/HttpClient/Response/HttplugPromise.php index f3806c9e53..2231464a22 100644 --- a/src/Symfony/Component/HttpClient/Response/HttplugPromise.php +++ b/src/Symfony/Component/HttpClient/Response/HttplugPromise.php @@ -11,6 +11,7 @@ namespace Symfony\Component\HttpClient\Response; +use function GuzzleHttp\Promise\promise_for; use GuzzleHttp\Promise\PromiseInterface as GuzzlePromiseInterface; use Http\Promise\Promise as HttplugPromiseInterface; use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface; @@ -31,7 +32,10 @@ final class HttplugPromise implements HttplugPromiseInterface public function then(callable $onFulfilled = null, callable $onRejected = null): self { - return new self($this->promise->then($onFulfilled, $onRejected)); + return new self($this->promise->then( + $this->wrapThenCallback($onFulfilled), + $this->wrapThenCallback($onRejected) + )); } public function cancel(): void @@ -62,4 +66,15 @@ final class HttplugPromise implements HttplugPromiseInterface return $result; } + + private function wrapThenCallback(?callable $callback): ?callable + { + if (null === $callback) { + return null; + } + + return static function ($value) use ($callback) { + return promise_for($callback($value)); + }; + } } diff --git a/src/Symfony/Component/HttpClient/Tests/Response/HttplugPromiseTest.php b/src/Symfony/Component/HttpClient/Tests/Response/HttplugPromiseTest.php new file mode 100644 index 0000000000..d781d4925b --- /dev/null +++ b/src/Symfony/Component/HttpClient/Tests/Response/HttplugPromiseTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Tests\Response; + +use GuzzleHttp\Promise\Promise; +use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpClient\Response\HttplugPromise; + +class HttplugPromiseTest extends TestCase +{ + public function testComplexNesting() + { + $mkPromise = function ($result): HttplugPromise { + $guzzlePromise = new Promise(function () use (&$guzzlePromise, $result) { + $guzzlePromise->resolve($result); + }); + + return new HttplugPromise($guzzlePromise); + }; + + $promise1 = $mkPromise('result'); + $promise2 = $promise1->then($mkPromise); + $promise3 = $promise2->then(function ($result) { return $result; }); + + $this->assertSame('result', $promise3->wait()); + } +}