Jdeferred
Java Deferred/Promise library similar to JQuery.
Install / Use
/learn @jdeferred/JdeferredREADME
JDeferred 2.x
JDeferred is a Java Deferred/Promise library similar to JQuery's Deferred Object.
Inspired by JQuery and Android Deferred Object.
If you are using JDeferred 1.x, see JDeferred 1.x Documentation
<a name="features"></a>Features
- Deferred object and Promise
- Promise callbacks
.then(…).filter(…).pipe(…).done(…).fail(…).progress(…).always(…).pipeAlways(…)
- Multiple promises
.when(p1, p2, p3, …).then(…).race(p1, p2, p3, …).then(…).settle(p1, p2, p3, …).then(…)
- Callable and Runnable wrappers
.when(new Runnable() {…}).race(new Runnable() {…}).settle(new Runnable() {…})
- Uses Executor Service
- Java Generics support
Deferred<Integer, Exception, Double> deferred;deferred.resolve(10);deferred.reject(new Exception());deferred.notify(0.80);
- Android Support
- Java 8 Lambda friendly
- Yes it's on Maven Central Repository!
Maven
<dependency>
<groupId>org.jdeferred.v2</groupId>
<artifactId>jdeferred-core</artifactId>
<version>${version}</version>
</dependency>
Gradle
compile 'org.jdeferred.v2:jdeferred-core:${version}'
Find available versions on Maven Central Repository.
<a name="compatibility"></a>Compatibility
Compatibility reports between versions:
<a name="examples"></a>Quick Examples
<a name="examples-deferred-promise"></a>Deferred object and Promise
Deferred deferred = new DeferredObject();
Promise promise = deferred.promise();
promise.done(new DoneCallback() {
public void onDone(Object result) {
...
}
}).fail(new FailCallback() {
public void onFail(Object rejection) {
...
}
}).progress(new ProgressCallback() {
public void onProgress(Object progress) {
...
}
}).always(new AlwaysCallback() {
public void onAlways(State state, Object result, Object rejection) {
...
}
});
With the reference to deferred object, you can then trigger actions/updates:
deferred.resolve("done");
deferred.reject("oops");
deferred.notify("100%");
<a name="example-filter"></a>Filter
Use
.filter(...)instead of.then(...)since 2.0.0-Beta2
Deferred d = …;
Promise p = d.promise();
Promise filtered = p.filter(new DoneFilter<Integer, Integer>() {
public Integer filterDone(Integer result)
return result * 10;
}
});
filtered.done(new DoneCallback<Integer>() {
public void onDone(Integer result) {
// result would be original * 10
System.out.println(result);
}
});
d.resolve(3) -> 30.
<a name="example-pipe"></a>Pipe
Use
.pipe(...)instead of.then(...)since 2.0.0-Beta2
Deferred d = ...;
Promise p = d.promise();
p.pipe(new DonePipe<Integer, Integer, Exception, Void>() {
public Deferred<Integer, Exception, Void> pipeDone(Integer result) {
if (result < 100) {
return new DeferredObject<Integer, Void, Void>().resolve(result);
} else {
return new DeferredObject<Integer, Void, Void>().reject(new Exception(...));
}
}
}).done(...).fail(...);
d.resolve(80) -> done!
d.resolve(100) -> fail!
<a name="example-dm"></a>Deferred Manager
DeferredManager dm = new DefaultDeferredManager();
Promise p1, p2, p3;
// initialize p1, p2, p3
dm.when(p1, p2, p3)
.done(…)
.fail(…)
You can also specify a Executor Service for your need.
DeferredManager dm = new DefaultDeferredManager(myExecutorService);
<a name="example-runnable-callable"></a>Runnable and Callable
You can use Callable and Runnable almost like a Promise without any additional work.
DeferredManager dm = new DefaultDeferredManager();
dm.when(new Callable<Integer>(){
public Integer call() {
// return something
// or throw a new exception
}
}).done(new DoneCallback<Integer>() {
public void onDone(Integer result) {
...
}
}).fail(new FailCallback<Throwable>() {
public void onFail(Throwable e) {
...
}
});
If you need to notify progress within your Callable or Runnable, you either need to create your own Deferred object and Promise, or you can use DeferredCallable and DeferredRunnable.
Use your own Deferred object
final Deferred deferred = ...
Promise promise = deferred.promise();
promise.then(…);
Runnable r = new Runnable() {
public void run() {
while (…) {
deferred.notify(myProgress);
}
deferred.resolve("done");
}
}
Or, extending DeferredRunnable
DeferredManager dm = …;
dm.when(new DeferredRunnable<Double>(){
public void run() {
while (…) {
notify(myProgress);
}
}
}).then(…);
<a name="example-wait"></a>Wait and WaitSafely
Since 1.0.1
Normally, when using this framework, you would want to do things asynchronously. However, if there is a need to wait for all deferred tasks to finish, you can use Object.wait or Promise.waitSafely methods.
Promise p = dm.when(...)
.done(...)
.fail(...)
synchronized (p)
while (p.isPending()) {
try {
p.wait();
} catch (InterruptedException e) { ... }
}
}
Alternatively, you can use a more simplified shortcut
Promise p = dm.when(...)
.done(...)
.fail(...)
try {
p.waitSafely();
} catch (InterruptedException e) {
...
}
<a name="example-lambda"></a>Java 8 Lambda
Now this is pretty cool when used with Java 8 Lambda!
dm.when(() -> {
return "Hey!";
}).done(r -> System.out.println(r));
dm.when(
() -> { return "Hello"; },
() -> { return "World"; }
).done(rs ->
rs.forEach(r -> System.out.println(r.getResult()))
);
<a name="example-race"></a>When
Calls to when with multiple arguments results in a Promise that signals fail on the first rejection or signals
done with all computed values.
Success scenario
Callable<Integer> c1 = () -> 1;
Callable<Integer> c2 = () -> 2;
Callable<Integer> c3 = () -> 3;
Promise<MultipleResults3<Integer, Integer, Integer>, OneReject<Throwable>, MasterProgress> p = dm.when(c1, c2, c3);
p.done(MultipleResults3<Integer, Integer, Integer> r -> {
Assert.assertEquals(r.getFirst(), 1);
Assert.assertEquals(r.getSecond(), 2);
Assert.assertEquals(r.getThird(), 3);
});
Failure scenario
Callable<Integer> c1 = () -> 1;
Callable<Integer> c2 = () -> 2;
Callable<Integer> c3 = () -> throw new RuntimeException("boom!");
Promise<MultipleResults3<Integer, Integer, Integer>, OneReject<Throwable>, MasterProgress> p = dm.when(c1, c2, c3);
p.done(MultipleResults3<Integer, Integer, Integer> r -> Assert.fail("should not be called"))
.fail(OneReject<Throwable> r -> Assert.assertEquals(r.getReject().getMessage(), "boom!"));
Since 2.0.0
Calls to when with multiple arguments (up to five) will produce results with typesafe getters.
<a name="example-when"></a>Race
Since 2.0.0
Calls to race with multiple arguments results in a Promise that signals fail on the first rejection or signals
done on the first resolution.
Success scenario
Callable<Integer> c1 = () -> { Thread.sleep(200); return 1; };
Callable<Integer> c2 = () -> { Thread.sleep(100); return 2; };
Callable<Integer> c3 = () -> { Thread.sleep(200); return 3; };
Promise<OneResult<?>, OneReject<Throwable>, Void> p = dm.race(c1, c2, c3);
p.done(OneResult<?> r -> Assert.assertEquals(r.getResult(), 2));
Failure scenario
Callable<Integer> c1 = () -> { Thread.sleep(200); return 1; };
Callable<Integer> c2 = () -> { Thread.sleep(100); throw new RuntimeException("boom!"); };
Callable<Integer> c3 = () -> { Thread.sleep(200); return 3; };
Promise<OneResult<?>, OneReject<Throwable>, Void> p = dm.race(c1, c2, c3);
p.done(OneResult<?> r -> Assert.fail("should not be called")
.fail(OneReject<Throwable> r -> Assert.assertEquals(r.getReject().getMessage(), "boom!"));
<a name="example-settle"></a>Settle
Since 2.0.0
Calls to settle with multiple arguments results in a Promise that collects all resolutions and rejections.
Callable<Integer> c1 = () -> { Thread.sleep(200); return 1; };
Callable<Integer> c2 = () -> { Thread.sleep(100); throw new RuntimeException("boom!"); };
Callable<Integer> c3 = () -> { Thread.sleep(200); return 3; };
Promise<AllValues, Throwable, MasterProgress>, Void> p = dm.race(c1, c2, c3);
p.done(AllValues r -> {
Assert.assertEquals(r.get(0).getValue(), 1);
Assert.assertTrue(r.get(1).getValue() instanceof RuntimeException);
Assert.assertEquals(r.get(2).getValue(), 3);
});
<a name="example-cancellation"></a>Cancellation Handler
Since 2.0.0
Sometimes a task may be cancelled while its running and would require ti cleanup any resources it may have allocated. You
may define a task that implements the org.jdeferred2.CancellationHandler interface or pass and extra argument to
DeferredFutureTask with such
Related Skills
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
96.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
