├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── org
│ └── riversun
│ └── promise
│ ├── Action.java
│ ├── Func.java
│ ├── Log.java
│ ├── Promise.java
│ ├── PromiseException.java
│ ├── Status.java
│ ├── SyncPromise.java
│ └── Thennable.java
└── test
└── java
└── org
└── riversun
└── promise
├── AppTest.java
├── TestPromiseAllAsync.java
├── TestPromiseAllSync.java
├── TestPromiseAllTestCase.java
├── TestPromiseAsync.java
├── TestPromiseSync.java
└── TestPromiseTestCase.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # for Eclipse
2 | .classpath
3 | .project
4 | .settings
5 |
6 | # for IDEA
7 | *.iml
8 | *.ipr
9 | *.iws
10 | .idea/
11 |
12 | # for build
13 | target
14 | build
15 |
16 | # for mac
17 | .DS_Store
18 |
19 | /bin/
20 | /examples/
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-2019 Tom Misawa
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Overview
2 | **java-promise** is a Promise Library for Java.
3 |
4 | - You can easily control asynchronous operations like JavaScript's **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**.
5 | - Supports both synchronous and asynchronous execution.
6 |
7 | It is licensed under [MIT](https://opensource.org/licenses/MIT).
8 |
9 | [](https://maven-badges.herokuapp.com/maven-central/org.riversun/java-promise)
10 |
11 |
12 | # Quick Look
13 |
14 | **Writing a Promise in Javascript**
15 |
16 | A typical example of using promise in JavaScript is:
17 |
18 | ```JavaScript
19 | Promise.resolve('foo')
20 | .then(function (data) {
21 | return new Promise(function (resolve, reject) {
22 | setTimeout(function () {
23 | const newData = data + 'bar';
24 | resolve(newData);
25 | }, 1);
26 | });
27 | })
28 | .then(function (data) {
29 | return new Promise(function (resolve, reject) {
30 | console.log(data);
31 | });
32 | });
33 | console.log("Promise in JavaScript");
34 | ```
35 |
36 | Result:
37 |
38 | ```
39 | Promise in JavaScript
40 | foobar
41 | ```
42 |
43 | **Writing a Promise in java-promise**
44 |
45 | Write the same thing using **java-promise**
46 |
47 | ```Java
48 | import org.riversun.promise.Promise;
49 | public class Example {
50 |
51 | public static void main(String[] args) {
52 | Promise.resolve("foo")
53 | .then(new Promise((action, data) -> {
54 | new Thread(() -> {
55 | String newData = data + "bar";
56 | action.resolve(newData);
57 | }).start();
58 | }))
59 | .then(new Promise((action, data) -> {
60 | System.out.println(data);
61 | action.resolve();
62 | }))
63 | .start();
64 | System.out.println("Promise in Java");
65 | }
66 | }
67 | ```
68 |
69 | Result:
70 |
71 | ```
72 | Promise in Java
73 | foobar
74 | ```
75 |
76 | **Syntax:**
77 | Yes,you can write in a syntax similar to JavaScript as follows:
78 |
79 | ```Java
80 | Promise.resolve()
81 | .then(new Promise(funcFulfilled1), new Promise(funcRejected1))
82 | .then(new Promise(functionFulfilled2), new Promise(functionRejected2))
83 | .start();
84 | ```
85 |
86 |
87 |
88 | # Dependency
89 |
90 | **Maven**
91 |
92 | ```xml
93 |
94 | org.riversun
95 | java-promise
96 | 1.1.0
97 |
98 | ```
99 |
100 | **Gradle**
101 |
102 | ```
103 | compile group: 'org.riversun', name: 'java-promise', version: '1.1.0'
104 | ```
105 |
106 | # Quick Start
107 |
108 | ### Execute sequentially by chained "then"
109 |
110 | - Use **Promise.then()** to chain operations.
111 | - Write your logic in **Func.run(action,data)**.
112 | - Start operation by **Promise.start** and run **asynchronously**(run on worker thread)
113 | - Calling **action.resolve** makes the promise **fullfilled** state and passes the **result** to the next then
114 |
115 | ```java
116 | public class Example00 {
117 |
118 | public static void main(String[] args) {
119 |
120 | Func function1 = (action, data) -> {
121 | new Thread(() -> {
122 | System.out.println("Process-1");
123 | try {
124 | Thread.sleep(500);
125 | } catch (InterruptedException e) {}
126 | //Specify result value.(Any type can be specified)
127 | action.resolve("Result-1");
128 | }).start();
129 | };
130 |
131 | Func function2 = (action, data) -> {
132 | System.out.println("Process-2 result=" + data);
133 | action.resolve();
134 | };
135 |
136 | Promise.resolve()
137 | .then(new Promise(function1))
138 | .then(new Promise(function2))
139 | .start();// start Promise operation
140 |
141 | System.out.println("Hello,Promise");
142 | }
143 | }
144 | ```
145 |
146 | **Diagram:**
147 |
148 |
149 | **Result:**
150 |
151 | ```
152 | Hello,Promise
153 | Process-1
154 | Process-1 result=Result-1
155 | ```
156 |
157 | **Tips**
158 |
159 | It's also OK to just write ``Promise.then(func) ``.
160 |
161 | ```Java
162 | Promise.resolve()
163 | .then(function1)
164 | .then(function2)
165 | .start();// start Promise operation
166 | ```
167 |
168 | # Description
169 | ### What is "**Func**" ?
170 |
171 | **Func** is a java interface equivalent to JavaScript's **Function** for argument of **#then**
172 |
173 | ```java
174 | public interface Func {
175 | public void run(Action action, Object data) throws Exception;
176 | }
177 | ```
178 |
179 | You can write **Func** like a JavaScript function.
180 | I want to show two ways of implementing **Func** class.
181 |
182 | No.1)Write **Func** object in the normal way.
183 |
184 | ```Java
185 | Func function = new Func() {
186 | @Override
187 | public void run(Action action, Object data) throws Exception {
188 | System.out.println("Process");//write your logic
189 | action.resolve();
190 | }
191 | };
192 | ```
193 |
194 | No.2)Write **Func** object using lambda expression.
195 |
196 | ```Java
197 | Func function = (action, data) -> {
198 | System.out.println("Process");//write your logic
199 | action.resolve();
200 | };
201 | ```
202 |
203 | ### What is "**Action**" ?
204 |
205 | Action object is an argument of **Func#run** method.
206 |
207 | - Call **action.resolve( [fulfillment value] )** to make the Promise's status **fulfilled** and move on to the next processing(specified by then) with the result(**fulfillment value**).
208 |
209 | ```Java
210 | action.resolve("Success");
211 | ```
212 |
213 | - Call **action.reject( [rejection reason] )** to make the Promise's status **rejected** and move on to the next processing(specified by then) with the result(**rejection reason**).
214 |
215 | ```Java
216 | action.reject("Failure");
217 | ```
218 |
219 | - Argument is optional, you can call **action.resolve()** or **action.reject()**
220 |
221 | ```Java
222 | action.resolve();//Argument can be omitted
223 | ```
224 |
225 | # Usage
226 |
227 | ### Rejection
228 |
229 | If **action.reject()** is called, or if an **exception thrown** while executing **Func.run()**, **rejected** status is set to Promise, and the **onRejected** function specified to **then** is called.
230 |
231 | - call ``action.reject``
232 |
233 | ```Java
234 | Func function = (action, data) -> {
235 | action.reject("Failure");
236 | };
237 | ```
238 |
239 | - throw an exception
240 |
241 | ```Java
242 | Func function = (action, data) -> {
243 | throw new Exception("something");
244 | };
245 |
246 | ```
247 |
248 | Let's see **Promise.then()** method,
249 | the **2nd argument** of **Promise.then()** can be set to a **Func** to receive the result of **rejection** when receiving the result of **then**.
250 |
251 | - **Syntax**
252 | Usage ``Promise.then(onFulfilled[, onRejected]);``
253 |
254 | - **onFulfilled** is a **Func** object called if the Promise is fulfilled.
255 | You can receive the previous execution **"fulfilled"** result as an argument named **data**.
256 |
257 | - **onRejected** is a **Func** object called if the Promise is rejected.
258 | You can receive the previous execution **"rejected"** result(mainly the objects are exceptions) as an argument named **data**.
259 |
260 | ```Java
261 | //Rejection
262 | public class ExampleRejection {
263 | public static void main(String[] args) {
264 | Promise.resolve()
265 | .then((action, data) -> {
266 | System.out.println("Process-1");
267 | action.reject();
268 | })
269 | .then(
270 | // call when resolved
271 | (action, data) -> {
272 | System.out.println("Resolved Process-2");
273 | action.resolve();
274 | },
275 | // call when rejected
276 | (action, data) -> {
277 | System.out.println("Rejected Process-2");
278 | action.resolve();
279 | })
280 | .start();// start Promise operation
281 |
282 | System.out.println("Hello,Promise");
283 | }
284 | }
285 | ```
286 |
287 | **Diagram:**
288 |
289 |
290 |
291 | **Result:**
292 |
293 | ```
294 | Hello,Promise
295 | Process-1
296 | Rejected Process-2
297 | ```
298 |
299 |
300 | ### Promise.always
301 |
302 | **Promise.always()** always receive both **fulfilled** and **rejected** results.
303 |
304 | ```Java
305 | public class ExampleAlways {
306 |
307 | public static void main(String[] args) {
308 | Func func2OutReject = (action, data) -> {
309 | action.reject("I send REJECT");
310 | //action.resolve("I send RESOLVE");
311 | };
312 | Func func2ReceiveAlways = (action, data) -> {
313 | System.out.println("Received:" + data);
314 | action.resolve();
315 | };
316 | Promise.resolve()
317 | .then(func2OutReject)
318 | .always(func2ReceiveAlways)
319 | .start();
320 | }
321 | }
322 | ```
323 |
324 | **Diagram:**
325 |
326 |
327 | **Result**
328 |
329 | ```
330 | Received:I send REJECT
331 | ```
332 |
333 | ### Promise.all
334 |
335 | Execute multiple promises at the same time, and after all executions are complete, move to the next processing with then
336 |
337 | - Execute multiple promises simultaneously and wait until all the execution is finished before proceeding.
338 | - If all finishes with resolve, execution results will be stored as **java.util.List