@@ -84,6 +84,149 @@ public function testAwaitReturnsValueWhenPromiseIsFulfilledEvenWhenOtherTimerSto
84
84
$ this ->assertEquals (2 , React \Async \await ($ promise ));
85
85
}
86
86
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
+
87
230
public function testAwaitShouldNotCreateAnyGarbageReferencesForResolvedPromise ()
88
231
{
89
232
if (class_exists ('React\Promise\When ' )) {
0 commit comments