Java Deferred/Promise library similar to JQuery.

Overview

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

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.

Compatibility

Compatibility reports between versions:

Quick Examples

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%");

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.

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!

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);

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(…);

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) {
  ... 
}

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()))
);

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.

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!"));

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);
});

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 implementation, for example

final DataSource datasource = ...;
class DatabaseTask extends Runnable, CancellationHandler {
  @Override
  public void run() {
    // perform computation with datasource
  }

  @Override
  public void onCancel() {
    try {
      datasource.close();
    } catch(Exception e) {
      throw new IllegalStateException(e);
    }
  }
}

DeferredFutureTask<X> task = new DeferredFutureTask(new DatabaseTask());
dm.when(task).done(...)

You may also pass the CancellationHandler as an additional argument, for example

final DataSource datasource = ...;
class DatabaseTask extends Runnable {
  @Override
  public void run() {
    // perform computation with datasource
  }
}

class DatabaseCancellationHandler implements CancellationHandler {
  @Override
  public void onCancel() {
    try {
      datasource.close();
    } catch(Exception e) {
      throw new IllegalStateException(e);
    }
  }
}

DeferredFutureTask<X> task = new DeferredFutureTask(new DatabaseTask(), new DatabaseCancellationHandler());
dm.when(task).done(...)

Groovy

You can also easily use with Groovy!

@Grab('org.jdeferred.v2:jdeferred-core:2.0.0')
import org.jdeferred2.*
import org.jdeferred2.impl.*

def deferred = new DeferredObject()
def promise = deferred.promise()

promise.done { result ->
  println "done: $result" 
}.fail { rejection ->
  println "fail: $rejection"
}.always { state, result, rejection ->
  println "always"
}

deferred.resolve("done")

Android Support

Since 1.1.0-Beta1

jdeferred-android is now available, and it can be included just like any other Android libraries! It also uses Android Maven plugin and builds apklib file. If you use Android Maven plugin, you can include dependency:

APKLIB with Maven:

<dependency>
  <groupId>org.jdeferred.v2</groupId>
  <artifactId>jdeferred-android</artifactId>
  <version>${version}</version>
  <type>apklib</type>
</dependency>

AAR with Maven:

Since 1.2.0-Beta1

<dependency>
  <groupId>org.jdeferred.v2</groupId>
  <artifactId>jdeferred-android-aar</artifactId>
  <version>${version}</version>
  <type>aar</type>
</dependency>

AAR with Gradle:

compile 'org.jdeferred.v2:jdeferred-android-aar:${version}'
// or
compile 'org.jdeferred.v2:jdeferred-android-aar:${version}@aar'

Find available versions on Maven Central Repository.

jdeferred-android introduces a new DeferredManager implementation called AndroidDeferredManager. AndroidDeferredManager makes sure that callbacks are executed in UI Thread rather than background Thread in order for callbacks to make UI updates. Alternatively, callbacks can also implement AndroidExecutionScopeable interface to fine-grain control whether the callback should execute in UI Thread or background Thread.

AndroidDeferredManager also supports new DeferredAsyncTask object. This object is based on Android's AsyncTask.

If you need to always execute callbacks in background thread, then you can continue to use DefaultDeferredManager.

Lastly, because JDeferred use SLF4J - you can further route log messages using slf4j-android.

Asynchronous Servlet

Here is a sample code on how to use JDeferred with Asynchronous Servlet!

@WebServlet(value = "/AsyncServlet", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  private ExecutorService executorService = Executors.newCachedThreadPool();
  private DeferredManager dm = new DefaultDeferredManager(executorService);

  protected void doGet(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
    final AsyncContext actx = request.startAsync(request, response);
    
    dm.when(new Callable<String>() {
      @Override
      public String call() throws Exception {
        if (actx.getRequest().getParameter("fail") != null) {
          throw new Exception("oops!");
        }
        Thread.sleep(2000);
        return "Hello World!";
      }
    }).then(new DoneCallback<String>() {
      @Override
      public void onDone(String result) {
        actx.getRequest().setAttribute("message", result);
        actx.dispatch("/hello.jsp");
      }
    }).fail(new FailCallback<Throwable>() {
      @Override
      public void onFail(Throwable exception) {
        actx.getRequest().setAttribute("exception", exception);
        actx.dispatch("/error.jsp");
      }
    });
  }
}
<script type="text/javascript"> /* */ </script> <script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js"> </script>

Deprecations

v1.2.5

  • DeferredManager.StartPolicy.MANAUL is deprecated and will be removed in the next minor version. Use DeferredManager.StartPolicy.MANUAL instead.
Comments
  • AndroidExecutionScope doesn't work

    AndroidExecutionScope doesn't work

    I'm trying to get certain callbacks to run in the background by using AndroidDeferredManager and Android****Callback functions that return AndroidExecutionScope.BACKGROUND in getExecutionScope(), but no matter what the callbacks always seem to execute on the main UI thread.

    This is the test I'm using to see which thread the callback is executing on:

      if (Looper.myLooper() == Looper.getMainLooper()) {
        Log.e(TAG, "bg thread on main"); 
      } else {
         Log.d(TAG, "bg thread on bg");
      }
    

    Even using DefaultDeferredManager, the callbacks run in the main UI thread. The only thing that does work is the DeferredAsyncTask passed to the AndroidDeferredManager, but I would like to be able to use the callbacks.

    If this is not a bug, please provide more documentation/examples on how to use these callbacks on Android.

    question 
    opened by jamchamb 15
  • 1.2.4 release to maven central?

    1.2.4 release to maven central?

    Hi, is there a plan to release v1.2.4 to maven central?
    I am interested in particular in the memory leak fix that was merged in 2ea5d9. I can pull the source myself, but it would be great to be able to pull in the jar the usual way via my pom file, etc.

    Thanks!

    opened by ggggl 12
  • FilteredPromise does not fail if filterDone fails

    FilteredPromise does not fail if filterDone fails

    I was trying to do a piped promise and I found out that on .then(DoneFilter) if the code on filterDone method fails with an exception the FilteredPromise does not fail

    This happens bacause at FilteredPromise:41 we don't catch any exceptions happened in filterDone. This may be by design but it is not what jQuery does, is it? Feels different.

    opened by mehiel 12
  • improve generics of promise

    improve generics of promise

    resolves #154

    Note: This is a breaking API change Never the less I think this will improve the experience of using jdeferred as the typing becomes more strict and therefore reduces possible runtime exceptions (such as ClassCastException)

    On the same time by using "? super" and "? extends" the typing becomes relaxed as we now can do the following

    Promise<Integer, Throwable, Void> integerPromise = createIntegerPromise();
    Promise<Float, Throwable, Void> floatPromise = createFloatPromise();
    integerPromise.then(Helper::numberLogger)
    floatPromise.then(Helper::numberLogger)
    

    where

    public class Helper {
        public void numberLogger(Number n) {
            /* log number */
        }
    }
    

    The Java Stream API also uses "? super" and "? extends" to allow maximal flexibility


    This change is Reviewable

    opened by sclassen 10
  • Adds the possibility to cancel all callbacks of a promise

    Adds the possibility to cancel all callbacks of a promise

    This method try to help apps developers that wan't to prevent leaks of Activity/Fragment when a user is leaving them and a promise is pending to be completed. Removing all callbacks let the Activity/Fragment to be garbage collected.


    This change is Reviewable

    help wanted 
    opened by raycoarana 9
  • Cancellation handler

    Cancellation handler

    As discussed during BaselOne, DeferredFutureTask is now able to cleanup any resources when the underlying task is interrupted or cancelled. Tests were parameterized with JUnitParams,


    This change is Reviewable

    enhancement 
    opened by aalmiray 8
  • Make jdeferred-android.jar available

    Make jdeferred-android.jar available

    While jdeferred-core.jar is available on Maven, jdeferred-android.jar is not (apklib, etc are there), and there seems to be no other distribution repository. This creates a high barrier to use for those people who don't use Maven.

    A related problem is that it's not documented which libraries are needed for an Android App: jdeferred-core jdeferred-android slf4j-api (this one is hard to guess from the myriad libraries for slf4j) slf4j-android

    enhancement 
    opened by capellsk 8
  • Added Exceptions.

    Added Exceptions.

    I've added the "except" tag to handle exceptions.

    Also, Mockito does RuntimeExceptions, so I am percolating at least the last RuntimeException that was recieved. It could be configured to do the first instead?


    This change is Reviewable

    opened by nwertzberger 8
  • With multiple results it is hard to access the cause of the failure

    With multiple results it is hard to access the cause of the failure

    On normal calls, the fail method has the exception as the parameter. When syncing multiple calls, the fail method returns a OneReject instance. But it is not easy (if even possible) to access the exception causing the failure through that instance. https://github.com/jdeferred/jdeferred/blob/master/subprojects/jdeferred-core/src/main/java/org/jdeferred/multiple/OneReject.java

    enhancement 
    opened by tbee 7
  • AndroidDeferredObject running callbacks in background thread

    AndroidDeferredObject running callbacks in background thread

    In Android I want to be able to run callbacks in background thread when resolve called from UI thread and AndroidExecutionScope.BACKGROUND passed in constructor. For example if i run this code in UI thread:

    DeferredObject deferred = new DeferredObject(); AndroidDeferredObject androidDeffered = new AndroidDeferredObject(deferred,AndroidExecutionScope.BACKGROUND);

    androidDeffered.then(new DoneCallback(){ // currently run in UI thread, suppose to be running in background thread });

    androidDeffered.resolve("Done");

    I don't want to use AndroidDefferedManager, since i want to return to my application Promise without done method and trigger it via resolve function.

    question 
    opened by korkag 7
  • Initial implementation of DeferredManager.settle

    Initial implementation of DeferredManager.settle

    DeferredManager.settle returns a Promise that's a composite of at least 2 runnables/callables/futures/promises. This promise contains the reject/resolve value of each runnable/callable/future/promise.

    This change is Reviewable

    enhancement 
    opened by aalmiray 6
  • Never call done when proguard enforcing

    Never call done when proguard enforcing

    when(...).done(my function) May lose effect when I turn on proguard. It seems like this plugin just execute code block which into brackets follow closely "when" and code block keep up with done will never be executed. ( Even if code in when block is empty ). I can not see any crash report or exception in logcat, and it seems like that thread exit after code block in brackets follow closely "when" execute finish. Turn off minify, this problem will be solved. Is there any keep rules about this project? This problem never occur in previous version( 1.x.x ).

    opened by ghost 3
  • Migrating from org.jdeferred 1.2.6 to 2.0.0

    Migrating from org.jdeferred 1.2.6 to 2.0.0

    I'm in the process of migrating from: implementation 'org.jdeferred:jdeferred-android-aar:1.2.6' to: implementation 'org.jdeferred.v2:jdeferred-android-aar:2.0.0'

    After replacing org.jdeferred with org.jdeferred2 everywhere, I got a last issue in a class named DeferredObjectWithExceptions. This extends DeferredObject and overrides the then method but this doesn't work anymore. And the new overridden methods don't work with my PipedPromiseWithExceptions class.

    First I get this errror:

    Type inference failed: constructor PipedPromiseWithExceptions<D, F, P, D_OUT, F_OUT, P_OUT>(promise: Promise<D#1 (type parameter of PipedPromiseWithExceptions), F#1 (type parameter of PipedPromiseWithExceptions), P#1 (type parameter of PipedPromiseWithExceptions)>, doneFilter: DonePipe<D#1, D_OUT#1 (type parameter of PipedPromiseWithExceptions), F_OUT, P_OUT>?, failFilter: FailPipe<F#1, D_OUT#1, F_OUT, P_OUT>?, progressFilter: ProgressPipe<P#1, D_OUT#1, F_OUT, P_OUT>?)
    cannot be applied to
    (DeferredObjectWithExceptions<D#2 (type parameter of DeferredObjectWithExceptions), F#2 (type parameter of DeferredObjectWithExceptions), P#2 (type parameter of DeferredObjectWithExceptions)>,DoneFilter<in D#2, out D_OUT#2 (type parameter of DeferredObjectWithExceptions.then)>?,Nothing?,Nothing?)
    

    This is my code file:

    import org.jdeferred2.DonePipe
    import org.jdeferred2.FailPipe
    import org.jdeferred2.ProgressPipe
    import org.jdeferred2.Promise
    
    class PipedPromiseWithExceptions<D, F, P, D_OUT, F_OUT, P_OUT>(
            promise: Promise<D, F, P>,
            doneFilter: DonePipe<D, D_OUT, F_OUT, P_OUT>?,
            failFilter: FailPipe<F, D_OUT, F_OUT, P_OUT>?,
            progressFilter: ProgressPipe<P, D_OUT, F_OUT, P_OUT>?) : DeferredObjectWithExceptions<D_OUT, F_OUT, P_OUT>(), Promise<D_OUT, F_OUT, P_OUT> {
        init {
            promise.done { result ->
                if (doneFilter != null) {
                    pipe(doneFilter.pipeDone(result))
                } else {
                    // Unchecked cast... but yea that is how PipedPromise.java normally works.
                    @Suppress("UNCHECKED_CAST")
                    resolve(result as D_OUT)
                }
            }.fail { result ->
                if (failFilter != null) {
                    pipe(failFilter.pipeFail(result))
                } else {
                    // Unchecked cast... but yea that is how PipedPromise.java normally works.
                    @Suppress("UNCHECKED_CAST")
                    reject(result as F_OUT)
                }
            }.progress { progress ->
                if (progressFilter != null) {
                    pipe(progressFilter.pipeProgress(progress))
                } else {
                    // Unchecked cast... but yea that is how PipedPromise.java normally works.
                    @Suppress("UNCHECKED_CAST")
                    notify(progress as P_OUT)
                }
            }
        }
    
        protected fun pipe(promise: Promise<D_OUT, F_OUT, P_OUT>): Promise<D_OUT, F_OUT, P_OUT> {
            promise.done { result -> resolve(result) }.fail { result -> reject(result) }.progress { progress -> notify(progress) }
            return promise
        }
    }
    
    

    When changing

    DonePipe<D, D_OUT, F_OUT, P_OUT>? -> DoneFilter<in D, out D_OUT>? FailPipe<F, D_OUT, F_OUT, P_OUT>? -> FailFilter<in F, out F_OUT>? ProgressPipe<P, D_OUT, F_OUT, P_OUT>? -> ProgressFilter<in P, out P_OUT>?

    I have an error in protected fun pipe(promise: D_OUT)

    How can I keep this working the way it was working in the old version?

    import org.jdeferred2.*
    import org.jdeferred2.impl.DeferredObject
    
    open class DeferredObjectWithExceptions<D, F, P> : DeferredObject<D, F, P>() {
    
        override fun <D_OUT : Any?> then(doneFilter: DoneFilter<in D, out D_OUT>?): Promise<D_OUT, F, P> {
            return PipedPromiseWithExceptions(this, doneFilter, null, null)
        }
    
        override fun <D_OUT : Any?, F_OUT : Any?> then(doneFilter: DoneFilter<in D, out D_OUT>?, failFilter: FailFilter<in F, out F_OUT>?): Promise<D_OUT, F_OUT, P> {
            return PipedPromiseWithExceptions(this, doneFilter, failFilter, null)
        }
    
        override fun <D_OUT : Any?, F_OUT : Any?, P_OUT : Any?> then(doneFilter: DoneFilter<in D, out D_OUT>?, failFilter: FailFilter<in F, out F_OUT>?, progressFilter: ProgressFilter<in P, out P_OUT>?): Promise<D_OUT, F_OUT, P_OUT> {
            return PipedPromiseWithExceptions(this, doneFilter, failFilter, progressFilter)
        }
    
    // This was working in 1.2.6:
    //    override fun <D_OUT, F_OUT, P_OUT> then(doneFilter: DonePipe<D, D_OUT, F_OUT, P_OUT>): Promise<D_OUT, F_OUT, P_OUT> {
    //        return PipedPromiseWithExceptions(this, doneFilter, null, null)
    //    }
    //
    //    override fun <D_OUT, F_OUT, P_OUT> then(doneFilter: DonePipe<D, D_OUT, F_OUT, P_OUT>, failFilter: FailPipe<F, D_OUT, F_OUT, P_OUT>): Promise<D_OUT, F_OUT, P_OUT> {
    //        return PipedPromiseWithExceptions(this, doneFilter, failFilter, null)
    //    }
    //
    //    override fun <D_OUT, F_OUT, P_OUT> then(doneFilter: DonePipe<D, D_OUT, F_OUT, P_OUT>, failFilter: FailPipe<F, D_OUT, F_OUT, P_OUT>, progressFilter: ProgressPipe<P, D_OUT, F_OUT, P_OUT>): Promise<D_OUT, F_OUT, P_OUT> {
    //        return PipedPromiseWithExceptions(this, doneFilter, failFilter, progressFilter)
    //    }
    }
    
    opened by JimClermonts 0
  • Notifications Can Be Lost

    Notifications Can Be Lost

    There is a race condition with progress notifications. A notification can occur before the progress callback is attached to a promise and unlike the reject or done callbacks which are stored and triggered they will be lost. I have a fix for it using a list that is flushed when the progress is attached.

    enhancement help wanted 
    opened by daiyzee 2
  • await function

    await function

    opened by EthanLozano 3
  • DonePipe cannot be use when() together

    DonePipe cannot be use when() together

    Here is the scenario in pseudo code with my case.

    private Promise<ObjectA, Exception, Double> grabObjectAandFilter() {
        return grabObjectA().then(new DoneFilter<ArrayList<ObjectA>, ObjectA>() {
            @Override
            public ObjectA filterDone(ArrayList<ObjectA> result) {
                // Do some filter
                return getFilteredOne();
            }
        });
    }
    
    private Promise<ArrayList<ObjectB>, OneReject<Object>, MasterProgress> grabB1andB2ThenMerge() {
        return dm.when(grabObjectB1(), grabObjectB2()
        ).then(new DoneFilter<MultipleResults2<ArrayList<ObjectB>, ArrayList<ObjectB>>, ArrayList<ObjectB>>() {
            @Override
            public ArrayList<ObjectB> filterDone(MultipleResults2<ArrayList<ObjectB>, ArrayList<ObjectB>> result) {
                ArrayList<ObjectB> list = new ArrayList<>();
                list.addAll(result.getFirst().getResult());
                list.addAll(result.getSecond().getResult());
                // Do some filter
                return list;
            }
        });
    }
    

    So here is my try.

    grabObjectAandFilter().then(new DonePipe<ObjectA, ArrayList<ObjectB>, OneReject<Object>, MasterProgress>() {
        @Override
        public Promise<ArrayList<ObjectB>, OneReject<Object>, MasterProgress> pipeDone(ObjectA result) {
            return grabB1andB2ThenMerge();
        }
    });
    

    I got this error

    error: no suitable method found for then(<anonymous DonePipe<ObjectA,ArrayList<ObjectB>,OneReject<Object>,MasterProgress>>)
    method Promise.then(DoneCallback<? super ObjectA>) is not applicable
    (argument mismatch; <anonymous DonePipe<ObjectA,ArrayList<ObjectB>,OneReject<Object>,MasterProgress>> cannot be converted to DoneCallback<? super ObjectA>)
    method Promise.<D_OUT#1>then(DoneFilter<? super ObjectA,? extends D_OUT#1>) is not applicable
    (cannot infer type-variable(s) D_OUT#1
    (argument mismatch; <anonymous DonePipe<ObjectA,ArrayList<ObjectB>,OneReject<Object>,MasterProgress>> cannot be converted to DoneFilter<? super ObjectA,? extends D_OUT#1>))
    method Promise.<D_OUT#2,F_OUT#1>then(DoneFilter<? super ObjectA,? extends D_OUT#2>,FailFilter<? super Exception,? extends F_OUT#1>) is not applicable
    (cannot infer type-variable(s) D_OUT#2,F_OUT#1
    (actual and formal argument lists differ in length))
    method Promise.<D_OUT#3,F_OUT#2,P_OUT#1>then(DoneFilter<? super ObjectA,? extends D_OUT#3>,FailFilter<? super Exception,? extends F_OUT#2>,ProgressFilter<? super Double,? extends P_OUT#1>) is not applicable
    (cannot infer type-variable(s) D_OUT#3,F_OUT#2,P_OUT#1
    (actual and formal argument lists differ in length))
    method Promise.<D_OUT#4>then(DonePipe<? super ObjectA,? extends D_OUT#4,? extends Exception,? extends Double>) is not applicable
    (cannot infer type-variable(s) D_OUT#4
    (argument mismatch; <anonymous DonePipe<ObjectA,ArrayList<ObjectB>,OneReject<Object>,MasterProgress>> cannot be converted to DonePipe<? super ObjectA,? extends D_OUT#4,? extends Exception,? extends Double>))
    method Promise.<D_OUT#5,F_OUT#3>then(DonePipe<? super ObjectA,? extends D_OUT#5,? extends F_OUT#3,? extends Double>,FailPipe<? super Exception,? extends D_OUT#5,? extends F_OUT#3,? extends Double>) is not applicable
    (cannot infer type-variable(s) D_OUT#5,F_OUT#3
    (actual and formal argument lists differ in length))
    method Promise.<D_OUT#6,F_OUT#4,P_OUT#2>then(DonePipe<? super ObjectA,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,FailPipe<? super Exception,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,ProgressPipe<? super Double,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>) is not applicable
    (cannot infer type-variable(s) D_OUT#6,F_OUT#4,P_OUT#2
    (actual and formal argument lists differ in length))
    where D_OUT#1,D,F,P,D_OUT#2,F_OUT#1,D_OUT#3,F_OUT#2,P_OUT#1,D_OUT#4,D_OUT#5,F_OUT#3,D_OUT#6,F_OUT#4,P_OUT#2 are type-variables:
    D_OUT#1 extends Object declared in method <D_OUT#1>then(DoneFilter<? super D,? extends D_OUT#1>)
    D extends Object declared in interface Promise
    F extends Object declared in interface Promise
    P extends Object declared in interface Promise
    D_OUT#2 extends Object declared in method <D_OUT#2,F_OUT#1>then(DoneFilter<? super D,? extends D_OUT#2>,FailFilter<? super F,? extends F_OUT#1>)
    F_OUT#1 extends Object declared in method <D_OUT#2,F_OUT#1>then(DoneFilter<? super D,? extends D_OUT#2>,FailFilter<? super F,? extends F_OUT#1>)
    D_OUT#3 extends Object declared in method <D_OUT#3,F_OUT#2,P_OUT#1>then(DoneFilter<? super D,? extends D_OUT#3>,FailFilter<? super F,? extends F_OUT#2>,ProgressFilter<? super P,? extends P_OUT#1>)
    F_OUT#2 extends Object declared in method <D_OUT#3,F_OUT#2,P_OUT#1>then(DoneFilter<? super D,? extends D_OUT#3>,FailFilter<? super F,? extends F_OUT#2>,ProgressFilter<? super P,? extends P_OUT#1>)
    P_OUT#1 extends Object declared in method <D_OUT#3,F_OUT#2,P_OUT#1>then(DoneFilter<? super D,? extends D_OUT#3>,FailFilter<? super F,? extends F_OUT#2>,ProgressFilter<? super P,? extends P_OUT#1>)
    D_OUT#4 extends Object declared in method <D_OUT#4>then(DonePipe<? super D,? extends D_OUT#4,? extends F,? extends P>)
    D_OUT#5 extends Object declared in method <D_OUT#5,F_OUT#3>then(DonePipe<? super D,? extends D_OUT#5,? extends F_OUT#3,? extends P>,FailPipe<? super F,? extends D_OUT#5,? extends F_OUT#3,? extends P>)
    F_OUT#3 extends Object declared in method <D_OUT#5,F_OUT#3>then(DonePipe<? super D,? extends D_OUT#5,? extends F_OUT#3,? extends P>,FailPipe<? super F,? extends D_OUT#5,? extends F_OUT#3,? extends P>)
    D_OUT#6 extends Object declared in method <D_OUT#6,F_OUT#4,P_OUT#2>then(DonePipe<? super D,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,FailPipe<? super F,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,ProgressPipe<? super P,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>)
    F_OUT#4 extends Object declared in method <D_OUT#6,F_OUT#4,P_OUT#2>then(DonePipe<? super D,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,FailPipe<? super F,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,ProgressPipe<? super P,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>)
    P_OUT#2 extends Object declared in method <D_OUT#6,F_OUT#4,P_OUT#2>then(DonePipe<? super D,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,FailPipe<? super F,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>,ProgressPipe<? super P,? extends D_OUT#6,? extends F_OUT#4,? extends P_OUT#2>)  
    
    opened by j796160836 2
Owner
JDeferred
JDeferred
Library to programatically return the name of fields similar to the C# nameof operator

nameof() A Java library to programmatically return the name of fields similar to the C# nameof expression How to use? The library is part of the Centr

MoebiusCode 12 Aug 10, 2022
CIRCUS - a Java and Spring Boot application for creating rooms with the purpose of watching YouTube videos together, similar to Watch2Gether

CIRCUS Video rooms application built using Apache Kafka, Java, Spring Boot, Spring Security and PostgreSQL About CIRCUS is a Java and Spring Boot appl

Castanho Correia 1 Jun 5, 2022
Similar to the minimap application, this program gets information from the center of the screen and displays information about that creature from a database.

New-World-CreatureInfo Similar to the minimap application, this program gets information from the center of the screen and displays information about

Mal Ball 2 Sep 21, 2022
Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.

Tinker Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstalling apk. Getting started Add t

Tencent 16.6k Dec 30, 2022
Trust-java - Test Results Verification library for Java

TRUST - Test Results Verification library for Java The TRUST's primary goal is to provide the simple way of different test results verification. Gener

Serhii Shymkiv 2 Nov 19, 2017
Create a Music Playlist Library -Core JAVA, JAVA Swing, AWT

Project Specifications Manage Everything about a basic Music Playlist Application in Java A Music Library for Listing, Replaying, Navigating between c

Muhammad Asad 7 Nov 8, 2022
Resconstruct is a java library to infer missing information vectors of java classes.

Reconstruct Resconstruct is a java library to infer missing information vectors of java classes. Features Phantom classes Inheritance solving Dummy fi

Nowilltolife 14 Nov 17, 2022
Z is a Java library providing accessible, consistent function combinators.

Fearless function combination in Java Techniques Unlock your functional programming potential with these combination techniques: Fusion Z.fuse(fn1, fn

J.R. 27 Jun 13, 2022
This is a small library written in Java for minecraft login.

minecraft-auth-library This is a small library written in Java for minecraft login. Usage: Login with microsoft MinecraftAuthenticator minecraftAuthen

Sandro 7 Feb 5, 2022
SpringBoot show case application for reactive-pulsar library (Reactive Streams adapter for Apache Pulsar Java Client)

Reactive Pulsar Client show case application Prerequisites Cloning reactive-pulsar Running this application requires cloning https://github.com/lhotar

Lari Hotari 9 Nov 10, 2022
A bitcoin explorer Java library that utilizes multiple data sources at once.

Bitcoin Explorer A bitcoin explorer library that utilizes multiple data sources at once. Branch Build Unit Tests master development Table of Contents

Scorpius 3 Jan 31, 2022
Nrich is a Java library developed at CROZ whose purpose is to make development of applications on JVM a little easier.

nrich Nrich is a Java library developed at CROZ whose purpose is to make development of applications on JVM a little easier. It contains modules that

CROZ 44 Nov 12, 2022
Portaudio4j - An exploratory project to interact with the PortAudio C library using Java's FFI (Panama) APIs

Examples of PortAudio called by Java's Panama APIs JEP 412. At the moment this is purely exploratory (still kicking the tires) as it progresses in the

Carl Dea 4 Dec 29, 2021
Tzatziki - Decathlon library to ease and promote Test Driven Development of Java microservices!

Tzatziki Steps Library This project is a collection of ready-to-use Cucumber steps making it easy to TDD Java microservices by focusing on an outside-

Decathlon 32 Dec 15, 2022
libraw4j - Java interface to the libraw library

libraw4j (1.0.0-SNAPSHOT) This is heavily W.I.P. Help is welcome! Java interface to the libraw library. Used for reading data from raw images. src/mai

Jacob Andersen 2 Apr 18, 2022
Java library to launch external processes

ch.vorburger.exec If you like/use this project, a Star / Watch / Follow me on GitHub is appreciated! This project is a small library allowing to launc

Michael Vorburger ⛑️ 25 Sep 7, 2022
A library to create, read and validate ZUGFeRD compliant invoices. Available for Java and .NET

Konik ZUGFeRD Library Is an easy to use open source implementation of the ZUGFeRD data model including various enhancements. Features Easy and underst

Konik 42 Dec 20, 2022
An advanced and highly optimized Java library to build framework

An advanced and highly optimized Java library to build frameworks: it's useful for scanning class paths, generating classes at runtime, facilitating the use of reflection, scanning the filesystem, executing stringified source code and much more...

Burningwave 119 Dec 21, 2022
OBKV Table Client is Java Library that can be used to access table data from OceanBase storage layer.

OBKV Table Client OBKV Table Client is Java Library that can be used to access table data from OceanBase storage layer. Its access method is different

OceanBase 12 Dec 16, 2022