Skip to content

Commit da37417

Browse files
Add standard convenience functions for creating Promises to resolve groups of Futures.
1 parent fe3368f commit da37417

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

src/lime/app/Promises.hx

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package lime.app;
2+
3+
import lime.app.Promise;
4+
import lime.app.Future;
5+
6+
/**
7+
* A set of static utility functions for working with Promises.
8+
* This includes functions which resolve groups of Futures.
9+
*/
10+
class Promises {
11+
/**
12+
* Creates a promise which fulfills when all the input promises resolve successfully,
13+
* with an array of the result values.
14+
* Rejects when any of the input promises reject, with the first rejection reason.
15+
* @param futures A list of Futures to resolve.
16+
* @return A Future for a list of result values.
17+
*/
18+
public static function all<T>(futures:Array<Future<T>>):Future<Array<T>> {
19+
var promise:Promise<Array<T>> = new Promise<Array<T>>();
20+
var results:Array<T> = [];
21+
22+
for (future in futures) {
23+
future.onComplete(function(result) {
24+
results.push(result);
25+
if (results.length == futures.length) {
26+
promise.complete(results);
27+
}
28+
});
29+
future.onError(function(error) {
30+
promise.error(error);
31+
});
32+
}
33+
34+
return promise.future;
35+
}
36+
37+
/**
38+
* Creates a promise which fulfills when all the input promises settle (whether success or failure).
39+
* Returns an array of objects that describe the outcome of each promise.
40+
* @param futures A list of Futures to resolve.
41+
* @return A Future for a list of result values.
42+
*/
43+
public static function allSettled<T>(futures:Array<Future<T>>):Future<Array<PromiseResult<T>>> {
44+
var promise:Promise<Array<PromiseResult<T>>> = new Promise<Array<PromiseResult<T>>>();
45+
var results:Array<PromiseResult<T>> = [];
46+
47+
for (future in futures) {
48+
future.onComplete(function(value) {
49+
results.push(PromiseResult.fulfilled(value));
50+
if (results.length == futures.length) {
51+
promise.complete(results);
52+
}
53+
});
54+
future.onError(function(error) {
55+
results.push(PromiseResult.rejected(value));
56+
if (results.length == futures.length) {
57+
promise.complete(results);
58+
}
59+
});
60+
}
61+
62+
return promise.future;
63+
}
64+
65+
/**
66+
* Creates a promise which fulfills when any of the input promises resolve successfully.
67+
* Returns the first fulfilled promise. If all promises reject, the promise will be rejected with the list of rejection reasons.
68+
* @param futures A list of Futures to resolve.
69+
* @return A Future for a result value.
70+
*/
71+
public static function any<T>(futures:Array<Future<T>>):Future<T> {
72+
var promise:Promise<T> = new Promise<T>();
73+
var errors:Array<Dynamic> = [];
74+
75+
for (future in futures) {
76+
future.onComplete(function(value) {
77+
promise.complete(value);
78+
});
79+
future.onError(function(error) {
80+
errors.push(error);
81+
if (errors.length == futures.length) {
82+
promise.error(errors);
83+
}
84+
});
85+
}
86+
87+
return promise.future;
88+
}
89+
90+
/**
91+
* Creates a promise which fulfills when any of the input promises settle.
92+
* Returns an object that describes the outcome of the first settled promise (whether success or failure).
93+
* @param futures A list of Futures to resolve.
94+
* @return A Future for a result value.
95+
*/
96+
public static function race<T>(futures:Array<Future<T>>):Future<PromiseResult<T>> {
97+
var promise:Promise<PromiseResult<T>> = new Promise<PromiseResult<T>>();
98+
for (future in futures) {
99+
future.onComplete(function(value) {
100+
promise.complete(PromiseResult.fulfilled(value));
101+
});
102+
future.onError(function(error) {
103+
promise.complete(PromiseResult.rejected(error));
104+
});
105+
}
106+
return promise.future;
107+
}
108+
}
109+
110+
class PromiseResult<T> {
111+
/**
112+
* The current state of the promise.
113+
*/
114+
public var state:PromiseState;
115+
/**
116+
* The value of the promise, if it resolved as Fulfilled.
117+
*/
118+
public var value:Null<T>;
119+
/**
120+
* The error of the promise, if it resolved as Rejected.
121+
*/
122+
public var error:Null<Dynamic>;
123+
124+
private function new(state:PromiseState, value:Null<T>, error:Null<Dynamic>):Void {
125+
this.state = state;
126+
this.value = value;
127+
this.error = error;
128+
}
129+
130+
public static function pending<T>():PromiseResult<T> {
131+
return new PromiseResult<T>(PromiseState.Pending, null, null);
132+
}
133+
134+
public static function fulfilled<T>(value:T):PromiseResult<T> {
135+
return new PromiseResult<T>(PromiseState.Fulfilled, value, null);
136+
}
137+
138+
public static function rejected<T>(error:Dynamic):PromiseResult<T> {
139+
return new PromiseResult<T>(PromiseState.Rejected, null, error);
140+
}
141+
}
142+
143+
enum PromiseState {
144+
/**
145+
* This promise has not yet resolved.
146+
*/
147+
Pending;
148+
/**
149+
* This promise has resolved with a value.
150+
*/
151+
Fulfilled;
152+
/**
153+
* This promise has resolved with an error.
154+
*/
155+
Rejected;
156+
}

0 commit comments

Comments
 (0)