@@ -82,6 +82,149 @@ public function testAwaitReturnsValueWhenPromiseIsFulfilledEvenWhenOtherTimerSto
82
82
$ this ->assertEquals (2 , React \Async \await ($ promise ));
83
83
}
84
84
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
+
85
228
public function testAwaitShouldNotCreateAnyGarbageReferencesForResolvedPromise ()
86
229
{
87
230
if (class_exists ('React\Promise\When ' ) && PHP_VERSION_ID >= 50400 ) {
0 commit comments