From ce2379f147a4f103fbca7b4ef09a48781f549dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 10 Feb 2022 14:06:41 +0100 Subject: [PATCH] Improve `async()` to avoid unneeded `futureTick()` calls --- src/functions.php | 2 +- tests/AsyncTest.php | 59 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/functions.php b/src/functions.php index cbd19fb..e016853 100644 --- a/src/functions.php +++ b/src/functions.php @@ -164,7 +164,7 @@ function async(callable $function): callable } }); - Loop::futureTick(static fn() => $fiber->start()); + $fiber->start(); }); } diff --git a/tests/AsyncTest.php b/tests/AsyncTest.php index ad856cb..dccbe54 100644 --- a/tests/AsyncTest.php +++ b/tests/AsyncTest.php @@ -8,25 +8,35 @@ use function React\Async\async; use function React\Async\await; use function React\Promise\all; +use function React\Promise\reject; +use function React\Promise\resolve; class AsyncTest extends TestCase { - public function testAsyncReturnsPendingPromise() + public function testAsyncReturnsPromiseThatFulfillsWithValueWhenCallbackReturnsValue() { $promise = async(function () { return 42; })(); - $promise->then($this->expectCallableNever(), $this->expectCallableNever()); + $value = null; + $promise->then(function ($v) use (&$value) { + $value = $v; + }); + + $this->assertEquals(42, $value); } - public function testAsyncReturnsPromiseThatFulfillsWithValueWhenCallbackReturns() + public function testAsyncReturnsPromiseThatFulfillsWithValueWhenCallbackReturnsPromiseThatFulfillsWithValue() { $promise = async(function () { - return 42; + return resolve(42); })(); - $value = await($promise); + $value = null; + $promise->then(function ($v) use (&$value) { + $value = $v; + }); $this->assertEquals(42, $value); } @@ -37,10 +47,41 @@ public function testAsyncReturnsPromiseThatRejectsWithExceptionWhenCallbackThrow throw new \RuntimeException('Foo', 42); })(); - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('Foo'); - $this->expectExceptionCode(42); - await($promise); + $exception = null; + $promise->then(null, function ($reason) use (&$exception) { + $exception = $reason; + }); + + assert($exception instanceof \RuntimeException); + $this->assertInstanceOf(\RuntimeException::class, $exception); + $this->assertEquals('Foo', $exception->getMessage()); + $this->assertEquals(42, $exception->getCode()); + } + + public function testAsyncReturnsPromiseThatRejectsWithExceptionWhenCallbackReturnsPromiseThatRejectsWithException() + { + $promise = async(function () { + return reject(new \RuntimeException('Foo', 42)); + })(); + + $exception = null; + $promise->then(null, function ($reason) use (&$exception) { + $exception = $reason; + }); + + assert($exception instanceof \RuntimeException); + $this->assertInstanceOf(\RuntimeException::class, $exception); + $this->assertEquals('Foo', $exception->getMessage()); + $this->assertEquals(42, $exception->getCode()); + } + + public function testAsyncReturnsPendingPromiseWhenCallbackReturnsPendingPromise() + { + $promise = async(function () { + return new Promise(function () { }); + })(); + + $promise->then($this->expectCallableNever(), $this->expectCallableNever()); } public function testAsyncReturnsPromiseThatFulfillsWithValueWhenCallbackReturnsAfterAwaitingPromise()