77use React \Promise \CancellablePromiseInterface ;
88use UnderflowException ;
99use Exception ;
10+ use React \Promise ;
1011
1112/**
1213 * wait/sleep for $time seconds
@@ -80,54 +81,28 @@ function ($error) use (&$exception, &$wait, $loop) {
8081 */
8182function awaitAny (array $ promises , LoopInterface $ loop )
8283{
83- $ wait = count ($ promises );
84- $ value = null ;
85- $ success = false ;
86-
87- foreach ($ promises as $ key => $ promise ) {
88- /* @var $promise PromiseInterface */
89- $ promise ->then (
90- function ($ return ) use (&$ value , &$ wait , &$ success , $ promises , $ loop ) {
91- if (!$ wait ) {
92- // only store first promise value
93- return ;
94- }
95- $ value = $ return ;
96- $ wait = 0 ;
97- $ success = true ;
98-
99- // cancel all remaining promises
100- foreach ($ promises as $ promise ) {
101- if ($ promise instanceof CancellablePromiseInterface) {
102- $ promise ->cancel ();
103- }
104- }
105-
106- $ loop ->stop ();
107- },
108- function ($ e ) use (&$ wait , $ loop ) {
109- if ($ wait ) {
110- // count number of promises to await
111- // cancelling promises will reject all remaining ones, ignore this
112- --$ wait ;
113-
114- if (!$ wait ) {
115- $ loop ->stop ();
116- }
117- }
118- }
119- );
120- }
84+ try {
85+ // Promise\any() does not cope with an empty input array, so reject this here
86+ if (!$ promises ) {
87+ throw new UnderflowException ('Empty input array ' );
88+ }
12189
122- while ($ wait ) {
123- $ loop ->run ();
124- }
90+ $ ret = await (Promise \any ($ promises )->then (null , function () {
91+ // rejects with an array of rejection reasons => reject with Exception instead
92+ throw new Exception ('All promises rejected ' );
93+ }), $ loop );
94+ } catch (Exception $ e ) {
95+ // if the above throws, then ALL promises are already rejected
96+ // (attention: this does not apply once timeout comes into play)
12597
126- if (!$ success ) {
127- throw new UnderflowException ('No promise could resolve ' );
98+ throw new UnderflowException ('No promise could resolve ' , 0 , $ e );
12899 }
129100
130- return $ value ;
101+ // if we reach this, then ANY of the given promises resolved
102+ // => try to cancel all promises (settled ones will be ignored anyway)
103+ _cancelAllPromises ($ promises );
104+
105+ return $ ret ;
131106}
132107
133108/**
@@ -147,49 +122,28 @@ function ($e) use (&$wait, $loop) {
147122 */
148123function awaitAll (array $ promises , LoopInterface $ loop )
149124{
150- $ wait = count ($ promises );
151- $ exception = null ;
152- $ values = array ();
153-
154- foreach ($ promises as $ key => $ promise ) {
155- /* @var $promise PromiseInterface */
156- $ promise ->then (
157- function ($ value ) use (&$ values , $ key , &$ wait , $ loop ) {
158- $ values [$ key ] = $ value ;
159- --$ wait ;
160-
161- if (!$ wait ) {
162- $ loop ->stop ();
163- }
164- },
165- function ($ e ) use ($ promises , &$ exception , &$ wait , $ loop ) {
166- if (!$ wait ) {
167- // cancelling promises will reject all remaining ones, only store first error
168- return ;
169- }
170-
171- $ exception = $ e ;
172- $ wait = 0 ;
173-
174- // cancel all remaining promises
175- foreach ($ promises as $ promise ) {
176- if ($ promise instanceof CancellablePromiseInterface) {
177- $ promise ->cancel ();
178- }
179- }
180-
181- $ loop ->stop ();
182- }
183- );
184- }
185-
186- while ($ wait ) {
187- $ loop ->run ();
125+ try {
126+ return await (Promise \all ($ promises ), $ loop );
127+ } catch (Exception $ e ) {
128+ // ANY of the given promises rejected
129+ // => try to cancel all promises (rejected ones will be ignored anyway)
130+ _cancelAllPromises ($ promises );
131+
132+ throw $ e ;
188133 }
134+ }
189135
190- if ($ exception !== null ) {
191- throw $ exception ;
136+ /**
137+ * internal helper function used to iterate over an array of Promise instances and cancel() each
138+ *
139+ * @internal
140+ * @param array $promises
141+ */
142+ function _cancelAllPromises (array $ promises )
143+ {
144+ foreach ($ promises as $ promise ) {
145+ if ($ promise instanceof CancellablePromiseInterface) {
146+ $ promise ->cancel ();
147+ }
192148 }
193-
194- return $ values ;
195149}
0 commit comments