mirror of
https://github.com/danog/amp.git
synced 2024-12-03 09:57:51 +01:00
Add defer()
This commit is contained in:
parent
3dbebd2a77
commit
40aab8eef5
@ -75,6 +75,18 @@ namespace Amp
|
||||
return static fn(mixed ...$args): Promise => async($callback, ...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given callback in a new green thread using {@see async()}, forwarding any exceptions thrown to
|
||||
* the event loop error handler using {@see Promise\rethrow()}.
|
||||
*
|
||||
* @param callable(mixed ...$args):void $callback
|
||||
* @param mixed ...$args
|
||||
*/
|
||||
function defer(callable $callback, mixed ...$args): void
|
||||
{
|
||||
Promise\rethrow(async($callback, ...$args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new function that wraps $callback in a promise/coroutine-aware function that automatically runs
|
||||
* Generators as coroutines. The returned function always returns a promise when invoked. Errors have to be handled
|
||||
@ -156,7 +168,7 @@ namespace Amp
|
||||
*
|
||||
* @deprecated No longer necessary with ext-fiber
|
||||
*/
|
||||
function call(callable $callback, ...$args): Promise
|
||||
function call(callable $callback, mixed ...$args): Promise
|
||||
{
|
||||
try {
|
||||
$result = $callback(...$args);
|
||||
@ -190,7 +202,7 @@ namespace Amp
|
||||
*
|
||||
* @deprecated No longer necessary with ext-fiber
|
||||
*/
|
||||
function asyncCall(callable $callback, ...$args): void
|
||||
function asyncCall(callable $callback, mixed ...$args): void
|
||||
{
|
||||
Promise\rethrow(call($callback, ...$args));
|
||||
}
|
||||
@ -203,6 +215,14 @@ namespace Amp
|
||||
return new Delayed($milliseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Async sleep for the specified number of milliseconds.
|
||||
*/
|
||||
function sleep(int $milliseconds): void
|
||||
{
|
||||
await(delay($milliseconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current time relative to an arbitrary point in time.
|
||||
*
|
||||
@ -212,14 +232,6 @@ namespace Amp
|
||||
{
|
||||
return Internal\getCurrentTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Async sleep for the specified number of milliseconds.
|
||||
*/
|
||||
function sleep(int $milliseconds): void
|
||||
{
|
||||
await(delay($milliseconds));
|
||||
}
|
||||
}
|
||||
|
||||
namespace Amp\Promise
|
||||
@ -249,7 +261,7 @@ namespace Amp\Promise
|
||||
* @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface.
|
||||
*
|
||||
*/
|
||||
function rethrow(Promise|ReactPromise $promise)
|
||||
function rethrow(Promise|ReactPromise $promise): void
|
||||
{
|
||||
if (!$promise instanceof Promise) {
|
||||
$promise = adapt($promise);
|
||||
@ -629,17 +641,15 @@ namespace Amp\Promise
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
function wrap($promise, callable $callback): Promise
|
||||
function wrap(Promise|ReactPromise $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();
|
||||
$deferred = new Deferred;
|
||||
|
||||
$promise->onResolve(static function (\Throwable $exception = null, $result) use ($deferred, $callback) {
|
||||
$promise->onResolve(static function (?\Throwable $exception, mixed $result) use ($deferred, $callback): void {
|
||||
try {
|
||||
$result = $callback($exception, $result);
|
||||
} catch (\Throwable $exception) {
|
||||
|
29
test/DeferTest.php
Normal file
29
test/DeferTest.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Amp\Test;
|
||||
|
||||
use Amp\Loop;
|
||||
use Amp\PHPUnit\AsyncTestCase;
|
||||
use Amp\PHPUnit\TestException;
|
||||
use function Amp\defer;
|
||||
use function Amp\sleep;
|
||||
|
||||
class DeferTest extends AsyncTestCase
|
||||
{
|
||||
public function testExceptionsRethrownToLoopHandler(): void
|
||||
{
|
||||
Loop::setErrorHandler(function (\Throwable $exception) use (&$reason): void {
|
||||
$reason = $exception;
|
||||
});
|
||||
|
||||
$exception = new TestException;
|
||||
|
||||
defer(function () use ($exception): void {
|
||||
throw $exception;
|
||||
});
|
||||
|
||||
sleep(0); // Tick event loop.
|
||||
|
||||
$this->assertSame($exception, $reason);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user