[HttpClient] fix chaining promises returned by HttplugClient

This commit is contained in:
cthulhu 2020-08-24 03:33:27 +03:00 committed by Nicolas Grekas
parent 1382001dfe
commit 75043a1fb0
2 changed files with 52 additions and 1 deletions

View File

@ -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));
};
}
}

View File

@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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());
}
}