@@ -84,6 +84,149 @@ public function testAwaitReturnsValueWhenPromiseIsFulfilledEvenWhenOtherTimerSto
8484 $ this ->assertEquals (2 , React \Async \await ($ promise ));
8585 }
8686
87+ public function testAwaitWithAlreadyFulfilledPromiseWillReturnWithoutRunningLoop ()
88+ {
89+ $ now = true ;
90+
91+ Loop::futureTick (function () use (&$ now ) {
92+ $ now = false ;
93+ });
94+
95+ $ promise = new Promise (function ($ resolve ) {
96+ $ resolve (42 );
97+ });
98+
99+ React \Async \await ($ promise );
100+ $ this ->assertTrue ($ now );
101+ }
102+
103+ public function testAwaitWithAlreadyFulfilledPromiseWillReturnWithoutStoppingLoop ()
104+ {
105+ $ ticks = 0 ;
106+
107+ $ promise = new Promise (function ($ resolve ) {
108+ $ resolve (42 );
109+ });
110+
111+ // Loop will execute this tick first
112+ Loop::futureTick (function () use (&$ ticks ) {
113+ ++$ ticks ;
114+ // Loop will execute this tick third
115+ Loop::futureTick (function () use (&$ ticks ) {
116+ ++$ ticks ;
117+ });
118+ });
119+
120+ // Loop will execute this tick second
121+ Loop::futureTick (function () use (&$ promise ){
122+ // await won't stop the loop if promise already resolved -> third tick will trigger
123+ React \Async \await ($ promise );
124+ });
125+
126+ Loop::run ();
127+
128+ $ this ->assertEquals (2 , $ ticks );
129+ }
130+
131+ public function testAwaitWithPendingPromiseThatWillResolveWillStopLoopBeforeLastTimerFinishes ()
132+ {
133+ $ promise = new Promise (function ($ resolve ) {
134+ Loop::addTimer (0.02 , function () use ($ resolve ) {
135+ $ resolve (2 );
136+ });
137+ });
138+
139+ $ ticks = 0 ;
140+
141+ // Loop will execute this tick first
142+ Loop::futureTick (function () use (&$ ticks ) {
143+ ++$ ticks ;
144+ // This timer will never finish because Loop gets stopped by await
145+ // Loop needs to be manually started again to finish this timer
146+ Loop::addTimer (0.04 , function () use (&$ ticks ) {
147+ ++$ ticks ;
148+ });
149+ });
150+
151+ // await stops the loop when promise resolves after 0.02s
152+ Loop::futureTick (function () use (&$ promise ){
153+ React \Async \await ($ promise );
154+ });
155+
156+ Loop::run ();
157+
158+ // This bahvior exists in v2 & v3 of async, we recommend to use fibers in v4 (PHP>=8.1)
159+ $ this ->assertEquals (1 , $ ticks );
160+ }
161+
162+ public function testAwaitWithAlreadyRejectedPromiseWillReturnWithoutStoppingLoop ()
163+ {
164+ $ ticks = 0 ;
165+
166+ $ promise = new Promise (function ($ _ , $ reject ) {
167+ throw new \Exception ();
168+ });
169+
170+ // Loop will execute this tick first
171+ Loop::futureTick (function () use (&$ ticks ) {
172+ ++$ ticks ;
173+ // Loop will execute this tick third
174+ Loop::futureTick (function () use (&$ ticks ) {
175+ ++$ ticks ;
176+ });
177+ });
178+
179+ // Loop will execute this tick second
180+ Loop::futureTick (function () use (&$ promise ){
181+ try {
182+ // await won't stop the loop if promise already rejected -> third tick will trigger
183+ React \Async \await ($ promise );
184+ } catch (\Exception $ e ) {
185+ // no-op
186+ }
187+ });
188+
189+ Loop::run ();
190+
191+ $ this ->assertEquals (2 , $ ticks );
192+ }
193+
194+ public function testAwaitWithPendingPromiseThatWillRejectWillStopLoopBeforeLastTimerFinishes ()
195+ {
196+ $ promise = new Promise (function ($ _ , $ reject ) {
197+ Loop::addTimer (0.02 , function () use (&$ reject ) {
198+ $ reject (new \Exception ());
199+ });
200+ });
201+
202+ $ ticks = 0 ;
203+
204+ // Loop will execute this tick first
205+ Loop::futureTick (function () use (&$ ticks ) {
206+ ++$ ticks ;
207+ // This timer will never finish because Loop gets stopped by await
208+ // Loop needs to be manually started again to finish this timer
209+ Loop::addTimer (0.04 , function () use (&$ ticks ) {
210+ ++$ ticks ;
211+ });
212+ });
213+
214+ // Loop will execute this tick second
215+ // await stops the loop when promise rejects after 0.02s
216+ Loop::futureTick (function () use (&$ promise ){
217+ try {
218+ React \Async \await ($ promise );
219+ } catch (\Exception $ e ) {
220+ // no-op
221+ }
222+ });
223+
224+ Loop::run ();
225+
226+ // This bahvior exists in v2 & v3 of async, we recommend to use fibers in v4 (PHP>=8.1)
227+ $ this ->assertEquals (1 , $ ticks );
228+ }
229+
87230 public function testAwaitShouldNotCreateAnyGarbageReferencesForResolvedPromise ()
88231 {
89232 if (class_exists ('React\Promise\When ' )) {
0 commit comments