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