Implementation of Promises/A+ in Java, plus various language sugars for programming. Java 6 or higher is required.
- Supports Promises/A+ specification, including thenable interface
- One of three separated interface sets can be chosen for coding
- Untyped: Promise class without Java Generics
- Typed: Promise class with Java Generics
- Light-weight: Short naming, and uses Throwable-only promise rejected reasons, suitable for cleaner codes
- Supports Java 8 Lambda
- Supports pre-built multi-argument (up to 5 arguments) fulfilled values (or rejected reasons) passing amount
.then()
method chaining - Can specify certain callbacks running on the specific
java.util.concurrent.Executor
context, which generally be different threads, even can be RPC calls by implementing the Executor interface - Utility methods convenient to switch between synchronous and asynchronous programming models
- (Not supported yet) Supports asynchronous sequential/parallel flow controls, such as if-then-else, switch-case, while, for, ...
- (Not supported yet) Promise causality logging for deep debugging/inspecting runtime execution sequences
import static promises.Promises.pf;
...
pf(null) // Returns fulfilled promises.Promise with null value
.then(dummy -> {
...
return "msg";
}) // Return type: promises.Promise
.then(
(String msg) -> { // Since promises.Promise has no type parameter, this lambda should specify the explicit argument type: String
...
return 123;
},
(reason, exception) -> { // Type of argument 'exception': Throwable
...
return 456;
}
) // Return type: promises.Promise
.then((Integer num) -> { // Since promises.Promise has no type parameter, this lambda should specify the explicit argument type: Integer
...
});
import static promises.typed.Promises.pf;
import static promises.typed.Promises.v;
...
pf(null) // Returns fulfilled promises.typed.Promise<Object, Object> with null value
.then(dummy -> {
...
return v("msg");
}) // Return type: promises.typed.Promise<String, Object>
.then(
msg -> { // Type of argument 'msg': String
...
return v(123);
},
(reason, exception) -> { // Type of argument 'reason': Object
...
return v(456);
}
) // Return type: promises.typed.Promise<Integer, Object>
.then(num -> { // Type of argument 'num': Integer
...
});
For simplicity, light-weight promise objects do not contain rejection reasons (only contain Throwable objects) to avoid specifying reason type parameter.
import static promises.lw.Promises.pf;
import static promises.lw.Promises.v;
...
pf(null) // Returns fulfilled promises.lw.P<Object> with null value
.then(dummy -> {
...
return v("msg");
}) // Return type: promises.lw.P<String>
.then(
msg -> { // Type of argument 'msg': String
...
return v(123);
},
exception -> { // Contains throwable-only argument for rejection
...
return v(456);
}
) // Return type: promises.lw.P<Integer>
.then(num -> { // Type of argument 'num': Integer
...
});
import static promises.typed.Promises.pf;
import static promises.typed.Promises.r;
import static promises.typed.Promises.v;
import static promises.typed.Promises.wf;
import static promises.typed.Promises.wr;
...
pf(null)
.then(dummy -> {
...
if (correct)
return v("msg", 123); // Fulfilled with ("msg", 123)
else
return r(404, "Not found", null); // Rejected with (404, "Not found"), null Throwable
})
.then(
wf((msg, num) -> { // Types of arguments: (String, Integer)
...
}),
wr((code, err, exception) -> { // Types of arguments: (Integer, String, Throwable)
...
})
);
import static promises.typed.Promises.pf;
...
pf(null)
.then(...)
.then(...)
...
.then(...)
.await(60, TimeUnit.SECONDS); // Waits for the overall promise chain being resolved
// When the chaining promise is fulfilled, the value would be returned
// When the chaining promise is rejected, promises.PromiseRejectedException containing rejected reason/exception would be thrown
// After 60 seconds without resolving, java.util.concurrent.TimeoutException would be thrown
import static promises.typed.Promises.async;
import static java.sql.Connection;
import static java.sql.PreparedStatement;
import static java.sql.ResultSet;
import static java.util.concurrent.Executor;
import static java.util.concurrent.Executors;
...
Executor exec = Executors.newSingleThreadExecutor(thread);
async(exec, () -> {
...
Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE name = ?");
stmt.setString(1, "UserName");
ResultSet rs = stmt.executeQuery();
...
return "msg";
})
.then(
msg -> { // When the synchronous callback successfully returns, the promise would be fulfilled with the returned value
...
},
(reason, exception) -> { // When an exception is thrown in the synchronous callback, the promise would be rejected with the thrown exception
...
}
);