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:
parent
1369f5fd47
commit
72378e2b82
@ -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
77
test/CallTest.php
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user