1
0
mirror of https://github.com/danog/amp.git synced 2024-11-30 04:29:08 +01:00

Add Amp\call()

This commit is contained in:
Aaron Piotrowski 2017-02-22 15:52:30 -06:00
parent 1369f5fd47
commit 72378e2b82
2 changed files with 104 additions and 0 deletions

View File

@ -55,6 +55,33 @@ function coroutine(callable $worker): callable {
};
}
/**
* Calls the given function, always returning a promise. If the function returns a Generator, it will be run as a
* coroutine. If the function throws, a failed promise will be returned.
*
* @param callable(mixed ...$args): mixed $functor
* @param array ...$args Arguments to pass to the function.
*
* @return \AsyncInterop\Promise
*/
function call(callable $functor, ...$args): Promise {
try {
$result = $functor(...$args);
} catch (\Throwable $exception) {
return new Failure($exception);
}
if ($result instanceof \Generator) {
return new Coroutine($result);
}
if (!$result instanceof Promise) {
return new Success($result);
}
return $result;
}
/**
* Registers a callback that will forward the failure reason to the Loop error handler if the promise fails.
*

77
test/CallTest.php Normal file
View File

@ -0,0 +1,77 @@
<?php
namespace Amp\Test;
use Amp;
use Amp\{ Coroutine, Success };
use AsyncInterop\Promise;
class CallTest extends \PHPUnit_Framework_TestCase {
public function testCallWithFunctionReturningPromise() {
$value = 1;
$promise = Amp\call(function ($value) {
return new Success($value);
}, $value);
$this->assertInstanceOf(Promise::class, $promise);
$promise->when(function ($exception, $value) use (&$reason, &$result) {
$reason = $exception;
$result = $value;
});
$this->assertNull($reason);
$this->assertSame($value, $result);
}
public function testCallWithFunctionReturningValue() {
$value = 1;
$promise = Amp\call(function ($value) {
return $value;
}, $value);
$this->assertInstanceOf(Promise::class, $promise);
$promise->when(function ($exception, $value) use (&$reason, &$result) {
$reason = $exception;
$result = $value;
});
$this->assertNull($reason);
$this->assertSame($value, $result);
}
public function testCallWithThrowingFunction() {
$exception = new \Exception;
$promise = Amp\call(function () use ($exception) {
throw $exception;
});
$this->assertInstanceOf(Promise::class, $promise);
$promise->when(function ($exception, $value) use (&$reason, &$result) {
$reason = $exception;
$result = $value;
});
$this->assertSame($exception, $reason);
$this->assertNull($result);
}
public function testCallWithGeneratorFunction() {
$value = 1;
$promise = Amp\call(function ($value) {
return yield new Success($value);
}, $value);
$this->assertInstanceOf(Coroutine::class, $promise);
$promise->when(function ($exception, $value) use (&$reason, &$result) {
$reason = $exception;
$result = $value;
});
$this->assertNull($reason);
$this->assertSame($value, $result);
}
}