SkillAgentSearch skills...

Jdeferred

Java Deferred/Promise library similar to JQuery.

Install / Use

/learn @jdeferred/Jdeferred
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<!-- Copyright 2013-2018 Ray Tsang Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -->

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

View on GitHub
GitHub Stars1.5k
CategoryDevelopment
Updated2d ago
Forks177

Languages

Java

Security Score

100/100

Audited on Mar 30, 2026

No findings