JDeferred


Source link: https://github.com/jdeferred/jdeferred

JDeferred

JDeferred is a Java Deferred/Promise library similar to JQuery's Deferred Object.

Inspired by JQuery and Android Deferred Object.

Features

  • Deferred object and Promise
  • Promise callbacks
    • .then(…)
    • .done(…)
    • .fail(…)
    • .progress(…)
    • .always(…)
  • Multiple promises
    • .when(p1, p2, p3, …).then(…)
  • Callable and Runnable wrappers
    • .when(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</groupId>     <artifactId>jdeferred-core</artifactId>     <version>${
version
}
</version> </dependency>

Gradle

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

Find available versions on Maven Central Repository.

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

Deferred d = …; Promise p = d.promise();
 Promise filtered = p.then(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

Since 1.1.0-Beta1

Deferred d = ...; Promise p = d.promise();
  p.then(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())) );

Groovy

You can also easily use with Groovy!

@Grab('org.jdeferred:jdeferred-core:1.2.6') import org.jdeferred.* import org.jdeferred.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 pugin and builts apklib file. If you use Android Maven plugin, you can include dependency:

APKLIB:

<dependency>
<groupId>org.jdeferred</groupId>
<artifactId>jdeferred-android</artifactId>
<version>...</version>
<type>apklib</type> </dependency>

AAR:

Since 1.2.0-Beta1

<dependency>
<groupId>org.jdeferred</groupId>
<artifactId>jdeferred-android-aar</artifactId>
<version>...</version>
<type>aar</type> </dependency>

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.

Resources

Android layout to show most common state templates like loading, empty, error etc. To do that all you need to is wrap the target area(view) with StatefulLayout.

Rx2Animations is a library with the main goal to make android animations more solid and cohesive.

A very simple library to change font to all of your views. This library will make your application have a default font display. Your application will not be affected by changes to the font type from the settings menu.

Android lib for easy set up custom font, can use for TextView, Button, CheckBox and EditText.

Historian is a custom implementation of Timber.Tree, which is popular logging library.

Historian can save device's logs into dedicated SQLite database, so that your users can send the file to a bug report mail to you.

Custom Android Bubbleview with curved Bezier Paths.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes