1
0
mirror of https://github.com/danog/amp.git synced 2024-11-26 20:15:00 +01:00

Add Promise\wrap (#234)

This commit is contained in:
Sascha-Oliver Prolic 2018-11-26 09:36:46 -09:00 committed by Niklas Keller
parent 9140197046
commit 96c2eeaa1f
2 changed files with 77 additions and 4 deletions

View File

@ -287,7 +287,7 @@ namespace Amp\Promise
* This function is the same as some() with the notable exception that it will never fail even * This function is the same as some() with the notable exception that it will never fail even
* if all promises in the array resolve unsuccessfully. * if all promises in the array resolve unsuccessfully.
* *
* @param Promise[] $promises * @param \Amp\Promise[]|\React\Promise\PromiseInterface[] $promises
* *
* @return \Amp\Promise * @return \Amp\Promise
* *
@ -303,7 +303,7 @@ namespace Amp\Promise
* promise succeeds with an array of values used to succeed each contained promise, with keys corresponding to * promise succeeds with an array of values used to succeed each contained promise, with keys corresponding to
* the array of promises. * the array of promises.
* *
* @param \Amp\Promise[] $promises Array of only promises. * @param \Amp\Promise[]|\React\Promise\PromiseInterface[] $promises Array of only promises.
* *
* @return \Amp\Promise * @return \Amp\Promise
* *
@ -354,7 +354,7 @@ namespace Amp\Promise
/** /**
* Returns a promise that succeeds when the first promise succeeds, and fails only if all promises fail. * Returns a promise that succeeds when the first promise succeeds, and fails only if all promises fail.
* *
* @param \Amp\Promise[] $promises Array of only promises. * @param \Amp\Promise[]|\React\Promise\PromiseInterface[] $promises Array of only promises.
* *
* @return \Amp\Promise * @return \Amp\Promise
* *
@ -407,7 +407,7 @@ namespace Amp\Promise
* *
* The returned promise will only fail if the given number of required promises fail. * The returned promise will only fail if the given number of required promises fail.
* *
* @param \Amp\Promise[] $promises Array of only promises. * @param \Amp\Promise[]|\React\Promise\PromiseInterface[] $promises Array of only promises.
* @param int $required Number of promises that must succeed for the returned promise to succeed. * @param int $required Number of promises that must succeed for the returned promise to succeed.
* *
* @return \Amp\Promise * @return \Amp\Promise
@ -471,6 +471,38 @@ namespace Amp\Promise
return $result; return $result;
} }
/**
* Wraps a promise into another promise, altering the exception or result.
*
* @param \Amp\Promise|\React\Promise\PromiseInterface $promise
* @param callable $callback
* @return Promise
*/
function wrap($promise, callable $callback): Promise
{
if ($promise instanceof ReactPromise) {
$promise = adapt($promise);
} elseif (!$promise instanceof Promise) {
throw createTypeError([Promise::class, ReactPromise::class], $promise);
}
$deferred = new Deferred();
$promise->onResolve(function (\Throwable $exception = null, $result) use ($deferred, $callback) {
try {
$result = $callback($exception, $result);
} catch (\Throwable $exception) {
$deferred->fail($exception);
return;
}
$deferred->resolve($result);
});
return $deferred->promise();
}
} }
namespace Amp\Iterator namespace Amp\Iterator

41
test/WrapTest.php Normal file
View File

@ -0,0 +1,41 @@
<?php
namespace Amp\Test;
use Amp\Deferred;
use Amp\Promise;
class WrapTest extends \PHPUnit\Framework\TestCase
{
public function testSuccess()
{
$deferred = new Deferred();
$promise = Promise\wrap($deferred->promise(), function () {
return 2;
});
$deferred->resolve(1);
$result = Promise\wait($promise);
$this->assertSame(2, $result);
}
/**
* @expectedException \Exception
* @expectedExceptionMessage bar
*/
public function testFailure()
{
$deferred = new Deferred();
$promise = Promise\wrap($deferred->promise(), function () {
throw new \Exception('bar');
});
$deferred->fail(new \Exception('foo'));
Promise\wait($promise);
}
}