Skip to content

Commit 27f0027

Browse files
committed
Improve await() in async() to avoid unneeded futureTick() calls
1 parent ce2379f commit 27f0027

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed

src/SimpleFiber.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function resume(mixed $value): void
2424
return;
2525
}
2626

27-
Loop::futureTick(fn() => $this->fiber->resume($value));
27+
$this->fiber->resume($value);
2828
}
2929

3030
public function throw(\Throwable $throwable): void
@@ -34,7 +34,7 @@ public function throw(\Throwable $throwable): void
3434
return;
3535
}
3636

37-
Loop::futureTick(fn() => $this->fiber->throw($throwable));
37+
$this->fiber->throw($throwable);
3838
}
3939

4040
public function suspend(): mixed

tests/AsyncTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use React;
66
use React\EventLoop\Loop;
7+
use React\Promise\Deferred;
78
use React\Promise\Promise;
89
use function React\Async\async;
910
use function React\Async\await;
@@ -84,6 +85,49 @@ public function testAsyncReturnsPendingPromiseWhenCallbackReturnsPendingPromise(
8485
$promise->then($this->expectCallableNever(), $this->expectCallableNever());
8586
}
8687

88+
public function testAsyncWithAwaitReturnsReturnsPromiseFulfilledWithValueImmediatelyWhenPromiseIsFulfilled()
89+
{
90+
$deferred = new Deferred();
91+
92+
$promise = async(function () use ($deferred) {
93+
return await($deferred->promise());
94+
})();
95+
96+
$return = null;
97+
$promise->then(function ($value) use (&$return) {
98+
$return = $value;
99+
});
100+
101+
$this->assertNull($return);
102+
103+
$deferred->resolve(42);
104+
105+
$this->assertEquals(42, $return);
106+
}
107+
108+
public function testAsyncWithAwaitReturnsPromiseRejectedWithExceptionImmediatelyWhenPromiseIsRejected()
109+
{
110+
$deferred = new Deferred();
111+
112+
$promise = async(function () use ($deferred) {
113+
return await($deferred->promise());
114+
})();
115+
116+
$exception = null;
117+
$promise->then(null, function ($reason) use (&$exception) {
118+
$exception = $reason;
119+
});
120+
121+
$this->assertNull($exception);
122+
123+
$deferred->reject(new \RuntimeException('Test', 42));
124+
125+
$this->assertInstanceof(\RuntimeException::class, $exception);
126+
assert($exception instanceof \RuntimeException);
127+
$this->assertEquals('Test', $exception->getMessage());
128+
$this->assertEquals(42, $exception->getCode());
129+
}
130+
87131
public function testAsyncReturnsPromiseThatFulfillsWithValueWhenCallbackReturnsAfterAwaitingPromise()
88132
{
89133
$promise = async(function () {

tests/AwaitTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@ public function testAwaitThrowsExceptionWhenPromiseIsRejectedWithException(calla
2222
$await($promise);
2323
}
2424

25+
/**
26+
* @dataProvider provideAwaiters
27+
*/
28+
public function testAwaitThrowsExceptionWithoutRunningLoop(callable $await)
29+
{
30+
$now = true;
31+
Loop::futureTick(function () use (&$now) {
32+
$now = false;
33+
});
34+
35+
$promise = new Promise(function () {
36+
throw new \Exception('test');
37+
});
38+
39+
try {
40+
$await($promise);
41+
} catch (\Exception $e) {
42+
$this->assertTrue($now);
43+
}
44+
}
45+
2546
/**
2647
* @dataProvider provideAwaiters
2748
*/
@@ -91,6 +112,24 @@ public function testAwaitReturnsValueWhenPromiseIsFullfilled(callable $await)
91112
$this->assertEquals(42, $await($promise));
92113
}
93114

115+
/**
116+
* @dataProvider provideAwaiters
117+
*/
118+
public function testAwaitReturnsValueImmediatelyWithoutRunningLoop(callable $await)
119+
{
120+
$now = true;
121+
Loop::futureTick(function () use (&$now) {
122+
$now = false;
123+
});
124+
125+
$promise = new Promise(function ($resolve) {
126+
$resolve(42);
127+
});
128+
129+
$this->assertEquals(42, $await($promise));
130+
$this->assertTrue($now);
131+
}
132+
94133
/**
95134
* @dataProvider provideAwaiters
96135
*/

0 commit comments

Comments
 (0)