Code Monkey home page Code Monkey logo

jdeferred's Issues

Running promises on specific threads

Hi

I was looking to start using promises to remove the callback hell I've accumulated in my application, but I need to be able to ensure that a promise is run in a specific thread pool.

I had thought that DefaultDeferredManager.when(Promise) would do just that, but in fact it does nothing.

I was thinking you'd need something like this:

   private static <D, F, P> Promise<D, F, P> schedule(Promise<D, F, P> promise, Executor exe)
   {
      ScheduledDeferredObject<D, F, P> mdo = new ScheduledDeferredObject<>(exe);
      promise.then((D d) -> mdo.resolve(d), (F f) -> mdo.reject(f), (P p) -> mdo.notify(p));
      return mdo;
   }

   private static class ScheduledDeferredObject<D, F, P> extends DeferredObject<D, F, P>
   {
      private final Executor executor;

      public ScheduledDeferredObject(Executor executor)
      {
         this.executor = executor;
      }

      @Override
      public Deferred<D, F, P> resolve(final D resolve)
      {
         executor.execute(() -> super.resolve(resolve));
         return this;
      }

      @Override
      public Deferred<D, F, P> reject(final F reject)
      {
         executor.execute(() -> super.reject(reject));
         return this;
      }

      @Override
      public Deferred<D, F, P> notify(final P progress)
      {
         executor.execute(() -> super.notify(progress));
         return this;
      }
   }

Regards
Stephen

Fork for a GWT open-source project

Hi Ray. I've forked the core part of your project to Turbo GWT (Core). I'll use it in the HTTP module, and I had to make a slight change on the AlwaysCalback (instead of just the State, I need a Context with more information). I've kept all the license/credits in the classes and in the main page of the Core project. Turbo GWT is under Apache2 license too. Thanks for your excellent work.

GWT and bridge to jQuery

Hello,
Thanks for jdeferred, this is a nice and clean piece that I was missing.
I forked it to add support for GWT:

lbovet@002eac3

I provided a wrapper to transparently bridge jQuery promises to JDeferred promises which can be really useful for people integrating GWT and jQuery.

I did not submit a pull request because I made a change in AbstractPromise replacing the CopyOnWriteArrayList with ArrayList since the former is not supported by GWT. This change is OK for the GWT case, as all changes occur in the same thread but is obviously not true in the general case.

I hope to find a way to instruct GWT to replace this class by itself and keep the codebase correct for the general use.

I also had to change the logging to use java.util.logging but this is less an issue, I think.

Can you have a look at this and tell me if you would consider integrating this in JDeferred?

ProgressPipe doesn't work

First, thanks for good work on this library.

I believe there's a problem on ProgressPipe.

deferred.then(null, null, new ProgressPipe<Double, Result, Exception, String> {
pipeProgress(Double percent) {
DeferredObject<Result, Exception, String> d = new ...
d.notify(percent * 100 + "%");
return d;
}
}).progress(new ProgressCallback() {
onProgress(String progress) {
// this will never get called.
}
}
deferred.notify(0.5);

I believe the reason is "ProgressCallback will not be called if we add it AFTER notify", I believe this is designed behavior. Like following:

deferred.notify(0.5);
deferred.progress(new ProgressCallback() {
void onProgress(Double progress) {
// this will never get called.
}
}

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!

DeferredCallable has different type parameters than Promise/Deferred

DeferredCallable has type parameters <D, P> while Promises have type parameters <D, F, P> . That means the Deferred in the DeferredCallable has error type "Throwable" instead of a user specified error type.

I'd like to specify my own error type with DeferredCallable. Was this difference intended or is it a TBD? Is there any reason not to add a type parameter for errors in DeferredCallable?

Promise.then(DoneCallback) does not fail if onDone fails

As a consequence of issue #7 piping seems a little bit broken (according to the jQuery standards again) on Promise.then(DoneCallback). The JavaDoc clearly says that this is equivalent to promise.done but according to piping it should fail if the DoneCallback fails.

This is again may be by design and if you feel this is wrong just close the issue.

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.

Source files without license headers

Hi
The following source files are without license headers:
./android/test/src/main/java/org/jdeferred/android/test/AndroidDeferredManagerTest.java
./android/test/src/main/java/org/jdeferred/android/test/MainActivity.java

./core/src/main/java/org/jdeferred/DeferredRunnable.java
./core/src/main/java/org/jdeferred/DeferredCallable.java

Please, confirm the licensing of code and/or content/s, and add license headers
https://fedoraproject.org/wiki/Packaging:LicensingGuidelines?rd=Packaging/LicensingGuidelines#License_Clarification

Thanks in advance
Regards

waitSafely does not work as expected

So, I have a small DeferredAsyncTask

public DeferredAsyncTask<Void, Integer, WebCall> getRequestTask(WebCall webcall) {
        return new DeferredAsyncTask<Void, Integer, WebCall>() {
            @Override
            protected WebCall doInBackgroundSafe(Void... voids) throws Exception {
                 //do stuff
                return webcall;
            }
        };
    }

that is called in a small flow

try {
    DeferredAsyncTask<Void, Integer, WebCall> requestTask = http.getRequestTask(webCall);
    new AndroidDeferredManager().when(requestTask).done(new DoneCallback<WebCall>() {
        @Override
        public void onDone(WebCall result) {
            value.set(result.getResponsePayload());
            Log.i(Constants.LOG_TAG, "webcall - result " + result.getResponsePayload());
        }
    }).fail(new FailCallback<Throwable>() {
        @Override
        public void onFail(final Throwable tr) {
            Log.i(Constants.LOG_TAG, "webcall - " + tr.getMessage());
        }
    }).waitSafely();
} catch (Exception e) {
    e.printStackTrace();
}

When using waitSafely() it just hangs. Nothing is written to the logcat, program execution is halted. Implementation seem to be fine according to the documentation. Any ideas?

Make a way to shove extra logging information into the MDC for promises as they resolve

Logging frameworks have a thing called an MDC. It's a way to store extra metadata that then gets logged with every message in that thread. They use ThreadLocal to implement this. With this move to promises, the thread a request is running on is not often the same one that initiated it.

I propose we add a boolean optional function call on promises, with a static global setter as well, that says to "preserveIssuerMdc" on promise resolutions.

If this is true, we build out the resolving thread's mdc to match the issuer's mdc exactly before calling promise callbacks.

The issuer is determined to be the caller of done(), fail(), progress(), then(). Every instantiation of this would store a reference to the parent mdc.

If anyone's interested, i'd be happy to make a fork to do this change. It might be somewhat expansive.

Returning a promise from a filter and add callbacks to that promise

This is based on #7 submitted by @mehiel, and his jquery example: http://jsfiddle.net/Bh8TA/1/

from @mehiel

Example 1: Throwing an excpetion on then's callback.
Outcome: @paolito is right. My assumption about exceptions was wrong, it is true that jQuery does not reject on uncaught exceptions. So jDeferred works as intended for this one.

Example 2: Filtering a value that came out of a promise.
Outcome: jDeferred also works as intended.

Example 3: Returning a promise from a DoneFilter and add callbacks to that promise.
Outcome: is jDeffered able to handle this situation? I think we're missing that. @paolito this is what you mentioned, isn't it?

from @paolito

What's missing in @jdeferred and would be extremely useful (see the last example at http://api.jquery.com/deferred.then/) is possibility for filters to return promise and have @jdeferred automatically rewire callbacks registred to promise created by then() to promise that will be returned from callback, when it is executed

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

Chained pipes in sequential order

Hi,
I'm trying to chain multiple pipes.

I'm facing the issue that the second pipe, which the code in block 3, is running in parallel with the block 2.

I know that I apparently would need to pipe the code in block 3 to the promise p2, but that doesn't feel right. Wouldn't it make more sense for p2 to replace p during the DonePipe?

How can I archive what I want, without nesting block 3 into the DonePipe.pipeDone of block 2? This means, how can I access p3 from outside of the wrapper it's running in, that is, at the same level as the promise p?

Could I pre-build the promises without making them execute, and then execute them later when required?

Thanks in advance.

final AndroidDeferredManager dm = new AndroidDeferredManager();

// block 1
Promise p = dm.when(new DeferredAsyncTask<Void, Integer, Object>() {
    @Override protected String doInBackgroundSafe(Void... nil) throws Exception {
        Log.v(TAG, "+++++++ BACKGROUND SLEEP");
        Thread.sleep(6000);
        Log.v(TAG, "+++++++ BACKGROUND RESUME");
        return "done";
    }
}).always(new AlwaysCallback<Object, Throwable>() {
    @Override
    public void onAlways(Promise.State state, Object o, Throwable throwable) {
        Log.v(TAG, "+++++++ ALWAYS " + state.toString() + " o: " + o + " t:" + throwable);
    }
});

// block 2
p.then(new DonePipe() {
    @Override public Promise pipeDone(Object o) {
        Promise p2 = dm.when(new DeferredAsyncTask<Void, Integer, Object>() {
            @Override protected String doInBackgroundSafe(Void... nil) throws Exception {
                Log.v(TAG, "+++++++ BACKGROUND SLEEP 2");
                Thread.sleep(4000);
                int i = 1 / 0;
                Log.v(TAG, "+++++++ BACKGROUND RESUME 2");
                return "done 2";
            }
        });
        return p2;
    }
}).always(new AlwaysCallback<Object, Throwable>() {
    @Override
    public void onAlways(Promise.State state, Object o, Throwable throwable) {
        Log.v(TAG, "+++++++ ALWAYS 2 " + state.toString() + " o: " + o + " t:" + throwable);
    }
});

// block 3
p.then(new DonePipe() {
    @Override public Promise pipeDone(Object o) {
        Promise p3 = dm.when(new DeferredAsyncTask<Void, Integer, Object>() {
            @Override protected String doInBackgroundSafe(Void... nil) throws Exception {
                Log.v(TAG, "+++++++ BACKGROUND SLEEP 3");
                Thread.sleep(4000);
                Log.v(TAG, "+++++++ BACKGROUND RESUME 3");
                return "done 3";
            }
        });
        return p3;
    }
}).always(new AlwaysCallback<Object, Throwable>() {
    @Override
    public void onAlways(Promise.State state, Object o, Throwable throwable) {
        Log.v(TAG, "+++++++ ALWAYS 3 " + state.toString() + " o: " + o + " t:" + throwable);
    }
});

How to chain several promises?

Using javascript promise libraries like "bluebird" i can return another promise inside "then" and call "then" again with the result of the last promise.

SocialAccount.forge({user_id: user.id, network: network}).fetch({require: true}).then(function(socialAccount) {
  return socialAccount.save({show_link: show === true ? 1 : 0}, {patch: true}); // Returns a new promise
}).then(function(socialAccount) {
  resolve(socialAccount);
}).catch(NotFoundError, function(err) {
  reject(messages.notFoundError('user.showNetwork.userNotConnected', 'The user is not connected to this network', err));
}).catch(function(err) {
  reject(messages.unexpectedError('user.showNetwork.error', 'Error setting network to show user link.', err));
});

It is possible to reproduce this example using JDeferred?
Thanks!

Catching and logging exceptions causes program to not notice.

Hey, when using JDeferred along with a netty-based program, I created a NullPointerException. Unfortunately, the promise i had was never rejected because the deferred object threw a null pointer exception. Here's an example:

final String str = null;
deferred.then( () -> otherPromise.resolve(null.size()) );

That nullpointerexception will just be eaten and never keyed off of. The only option i see is to wrap everything in these try {} catch(Exception e){} blocks, but i'd rather be able to have an "except" tag or something to deal with caught exceptions ( for example)

final String str = null;
deferred.then( () -> otherPromise.resolve(null.size()) )
    .except((e) -> otherpromise.reject());

Passing non-void parameters to the DeferredAsyncTask

I've been trying to replace the

new DeferredAsyncTask<Void, Throwable, Object>

with a

class DeferredFlowControl {
    String mURL = "...";
    String mDownloadResult = null;
    String mFilename = "...";
    String mSaveResult = null;
}
final DeferredFlowControl dfcSequence = new DeferredFlowControl();

new DeferredAsyncTask<DeferredFlowControl, Throwable, Object>

but I can't find a way to make use of that DeferredFlowControl instance named dfcSequence.

I could make the tasks read/write the variables of the dfcSequence directly, but I'm trying to pass that dfcSecuence around as a parameter, as I can do with normal AsyncTasks, by passing it to the AsyncTask.execute(dfcSequence);

Is it possible to do this? The DeferredAsyncTask never gets to call the doInBackgroundSafe, as a java.lang.ClassCastException: java.lang.Void[] cannot be cast to .....$1DeferredFlowControl exception is raised.

Readme issue

In the Filter section, you use a P instead of a {.

public Integer filterDone(Integer result) P
return result * 10;
}

Support for a whenAny method

Would it be possible to support a whenAny method where you can have several Callables that as soon as one is successfully returned, the DoneCallback with the result is called with the result (and canceling/failing all remaining Callables if they can be canceled)?

Here's a unit test for the use case:

@Test(timeout = 3000)
public void testWhenAny() {
    final AtomicInteger doneCount = new AtomicInteger();
    final AtomicInteger failCount = new AtomicInteger();
    final AtomicBoolean callable1Run = new AtomicBoolean(false);
    final AtomicBoolean callable2Run = new AtomicBoolean(false);
    final AtomicBoolean callable3Run = new AtomicBoolean(false);

    Promise<OneResult, OneReject, MasterProgress> p = deferredManager.whenAny(new Callable<Integer>() {
        public Integer call() {
            try {
                Thread.sleep(2000);
                callable1Run.set(true);
            } catch (InterruptedException e) {
            }

            return 100;
        }
    }, new Callable<Integer>() {
        public Integer call() {
            try {
                Thread.sleep(500);
                callable2Run.set(true);
            } catch (InterruptedException e) {
            }

            throw new RuntimeException("Oops");
        }
    }, new Callable<String>() {
        public String call() {
            try {
                Thread.sleep(5000);
                callable3Run.set(true);
            } catch (InterruptedException e) {
            }

            return "Hello";
        }
    }).then(new DoneCallback<OneResult>() {
        public void onDone(OneResult result) {
            Assert.assertEquals(100, result.getResult());
            doneCount.incrementAndGet();
        }
    }).fail(new FailCallback<OneReject>() {
        public void onFail(OneReject result) {
            if (failCount.incrementAndGet() == 1) {
                Assert.assertEquals(RuntimeException.class, result.getReject().getClass());
                RuntimeException e = (RuntimeException) result.getReject();
                Assert.assertEquals("Oops", e.getMessage());
            }
        }
    });

    Assert.assertTrue(callable1Run.get());
    Assert.assertTrue(callable2Run.get());
    Assert.assertFalse(callable3Run.get());
    Assert.assertEquals(1, doneCount.get());
    Assert.assertEquals(2, failCount.get());
}

How to create rejected promise?

Hello. Thanks for the project.
So, a little question - how I can create rejected promise? For example:

Promise downloadFile(String url, String localPath) {
        try {
            return downloadFile(new URL(url), localPath);
        } catch (MalformedURLException e) {
            return ????; // I want to return simple rejected Promise, in one line. How?
        }
}
Promise downloadFile(URL url, String localPath) {
        /// ... DeferredAsyncTask, etc
}

Thanks in advice

waitSafely - why does this work?

I opened a question on StackOverflow and have found a solution, but I don't fully understand why it works. The solution appears related to jdeferred, so I thought you might be able to shed light on it.

I am using waitSafely to test code that is run in a thread. My broken code looked like this:

    Promise prom = client.find(new VideoQueue())
            .set("user", "212139")
            .run()
            .done(new DoneCallback<ArrayList<VideoQueue>>() {
                @Override
                public void onDone(ArrayList<VideoQueue>  videoQueue) {
                    assertNotNull(videoQueue);
                    assertNotNull(videoQueue.get(0));
                    assertNotNull(videoQueue.get(0).getId());
                    assertEquals("3310190", videoQueue.get(0).getId());
                }
            }).fail(new FailCallback() {
                @Override
                public void onFail(Object rejection) {
                    assertNull(rejection);
                }
            });

    prom.waitSafely();

The result was that the test runner would fully exit when an assertion failed. After moving waitSafely before done, the issue has resolved itself. The assertion fails, but the runner continues through the other tests. The code below works.

        Promise prom = client.find(new VideoQueue())
                .set("user", "212139")
                .run();

        prom.waitSafely();

        prom.done(new DoneCallback<ArrayList<VideoQueue>>() {
                    @Override
                    public void onDone(ArrayList<VideoQueue>  videoQueue) {
                        assertNotNull(videoQueue);
                        assertNotNull(videoQueue.get(0));
                        assertNotNull(videoQueue.get(0).getId());
                        assertEquals("3310190", videoQueue.get(0).getId());
                    }
                }).fail(new FailCallback() {
                    @Override
                    public void onFail(Object rejection) {
                        fail();
                    }
                });

Do you have any insight into why this change works?

vertx support

Provide support for vert.x so that the same paradigm/interfaces can work seamlessly in vert.x

Cancel functionality

Cancel functionality is missing:
Missing State.CANCELED with cancel() method and onCancel listener. If promise is in pending state and cancel method was called, move the state to CANCELED, call onCancel method.

jdeferred-parent in MavenCentral is out of date

I'm trying to include jdeferred-core into an android app using gradle like so:

dependencies {
    compile 'org.jdeferred:jdeferred-core:1.0.0'
}

I get an error when doing ./gradlew clean build:

* What went wrong:
A problem occurred configuring project ':MyApp'.
> Failed to notify project evaluation listener.
   > Could not resolve all dependencies for configuration ':MyApp:_DebugCompile'.
      > Could not resolve org.jdeferred:jdeferred-core:1.0.1.
        Required by:
            MyApp:MyApp:unspecified
         > Could not find any version that matches org.jdeferred:jdeferred-parent:1.0.1.

I checked out Maven central, and though it appears that jdeferred and jdeferred-core have v1.0.1s, jdeferred-parent is v1.0.0, which I believe is causing there error.

I worked around it by just using jdeferred-core:1.0.0 but I thought I'd bring it up.

Usage with network calls, errors swallowed

Trying to have network calls run with jdeferred, but responses never seem to return and errors are swallowed. Is there a better way to do the below? This is in an Android lib module, being tested on a junit module. Side note: the lambdas work on Android using Retrolambda

Below uses org.apache.http (had an initial working version with futures from Async-Http-Client, but Android said it was making network calls on the main thread)

private static final  Promise __getRequest(String url) {
       Deferred d = new DeferredObject();
        Promise p = d.promise();
        //AndroidDeferredManager adm = new AndroidDeferredManager();
        DeferredManager dm = new DefaultDeferredManager();

        final HttpParams httpParameters = new BasicHttpParams(); // Have also tried putting these in the lambda
        final HttpClient client = new DefaultHttpClient(httpParameters);
        final HttpGet method = new HttpGet(url); // url string

        dm.when(() -> {
            try {
                HttpResponse response = client.execute(method); // *** Gets here, then dies on step-over, no error thrown, nothing.

                String result = EntityUtils.toString(response.getEntity(), "UTF-8");
                return result;
            } catch (Exception e) {
                return "frick"; // Never gets here
            }
        }).done(result -> {
            // Do stuff (never gets here)
            // has d.resolve(<stuff>)
        }).fail(error -> {
            // Never gets here either
            // has d.reject(error)
        });

        return p;
    }

Appreciate the help.
PS Should I be posting this on SO instead of here?

Is AndroidDeferredManager always return MultipleResults in the same order?

I just need confirmation, from the following snippets:

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        AndroidDeferredManager androidDeferredManager = new AndroidDeferredManager();
        androidDeferredManager
                .when(new Callable<Object>() {
                            @Override
                            public String call() throws Exception {
                                Thread.sleep(3000);
                                return "Hello World 1!";
                            }
                        },
                        new Callable<Object>() {
                            @Override
                            public String call() throws Exception {
                                Thread.sleep(2000);
                                return "Hello World 2!";
                            }
                        },
                        new Callable<Object>() {
                            @Override
                            public String call() throws Exception {
                                Thread.sleep(1000);
                                return "Hello World 3!";
                            }
                        },
                        new Callable<Object>() {
                            @Override
                            public String call() throws Exception {
                                Thread.sleep(1900);
                                return "Hello World 4!";
                            }
                        })
        .done(new DoneCallback<MultipleResults>() {
            @Override
            public void onDone(MultipleResults result) {
                for(OneResult res: result){
                    Log.d("LOG", "Result: " + res.toString());
                }
            }
        });
    }
});

I saw the following logs:

08-11 11:21:57.853    6234-6234/id.flwi.deferredtesting D/LOG﹕ Result: OneResult [index=0, promise=org.jdeferred.android.AndroidDeferredObject@533e7b78, result=Hello World 1!]
08-11 11:21:57.853    6234-6234/id.flwi.deferredtesting D/LOG﹕ Result: OneResult [index=1, promise=org.jdeferred.android.AndroidDeferredObject@533e990c, result=Hello World 2!]
08-11 11:21:57.853    6234-6234/id.flwi.deferredtesting D/LOG﹕ Result: OneResult [index=2, promise=org.jdeferred.android.AndroidDeferredObject@533e9a94, result=Hello World 3!]
08-11 11:21:57.853    6234-6234/id.flwi.deferredtesting D/LOG﹕ Result: OneResult [index=3, promise=org.jdeferred.android.AndroidDeferredObject@533e9c28, result=Hello World 4!]

Result is always in that order. So again, Is MultipleResults always came in the same order?

AndroidDeferredManager javadoc typo

On line 137, you say:

If this a non-Android friendly promise is passed in, wrap it with {@link AndroidDeferredObject} so that callbacks can be executed in UI thread.

I think you meant to say

If this is ...

and

... be executed in the UI thread.

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.

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.

Notify progress

How do I notify the progress from a Deferred object? I have the following code:

    Deferred<String, Exception, String> d = new DeferredObject<>();
    Promise<String, Exception, String> p = d.promise();
    new Thread(() -> {
        for (String name : names) {
            String expensiveOperationStepOutput = reallyExpensiveFunction(name)
            d.notify("Actual notification");
            System.out.println("Notified");
        }
        d.resolve("done");
    }).run();
    return p;

And then somewhere I do:

    Promise<String, Exception, String> p = sm.fetchExpensiveThings();
    p.then(result -> {
        System.out.println("Done!");
    });
    p.progress(progress -> System.out.println("Called!"));

But when I run the above code, I see a lot of "Notified" and a "Done" at the end, but never "Called". How do I do this?

FAQ: how to asynchronously create a chain of deffered.

Hi all.
I am quite newbie with jdeffered terminology.
I will try to tell my problem.
And expect that you can translate it correctly in JDeffered terms.

Use case:
I have a big file containing a list of URLs.
I just have an implemented method called getContentFromTheWeb().
That method accepts a URL string as parameter and return as a String the corresponding content from the Web.

I wish I could use a syntax a la JDeffered to run this kind of code:
readURLsFromFileAsynchronously().asSoonAsAURLIsReadDoAsynchronously(getContentFromTheWeb(url)).afterAllURLsWereRetrieved(zipTheContents(listOfContentsAsString))

I am not sure JDeffered has such a direct compact syntax for this use case.
Anyway I hope gurus can help me get the shortest JDeffered code that implements this use case.
That would help me understand the underlying philosophy of JDeffered.

Any help is welcome.

Support for array of Callables/Promises on then (Promise.all)

If we need to assure execution of all callables before calling the next in line, in a pipe, we have to do this:

final List<Callable<String>> callables = ImmutableList.of(callable1, callable2);

dm.when(doCall1)
  .then(new DonePipe<String, MultipleResults, OneReject, MasterProgress>() {
                    @Override
                    public Promise<MultipleResults, OneReject, MasterProgress> pipeDone(String result) {
                        return dm.when(callables.toArray(new Callable[callables.size()]));
                    }
                })
  .then(new DoneCallback<MultipleResults>() {
                    @Override
                    public void onDone(MultipleResults result) {
                        System.out.println("Now all the callables have finished");
                    }
                });

Instead, we should be able to do something like:

final List<Callable<String>> callables = ImmutableList.of(callable1, callable2);

dm.when(doCall1)
  .then(Promise.all(callables))
  .then(new DoneCallback<List<String>>() {
                    @Override
                    public void onDone(List<String> result) {
                        System.out.println("Now all the callables have finished");
                    }
                });

wait(timeout)

Any chance of getting a Promise.wait(timeout) function added? This would be a nice addition when the need arises to block while several promises are completing in a DeferredManager. While, you would say that you continue the async tasks in a dm.then() handler, there are some situations with some web frameworks where blocking to continue in a synchronous manner are helpful.

Add Uncaught Exception Handler

In DeferredManager, add ability to register a catch all uncaught exception handler. In case any Throwable was uncaught, pass it to the handler.

Applications should always try to handle known exceptions in the fail() handler explicitly. This is as a last-resort fallback.

By default, the handler will log the uncaught exception.

Enhancement: allow filterDone throw exception.

Currently we cannot throw exception in filterDone, a better approach is capture the exception in FilteredPromise and mark it as rejected. Let me use an example to explain this.

We need to do two things, one is get data through http, the other is convert the data (string) to domain object.

XHR.get(url).then(new DoneFilter<String, DomainObject>() {
DomainObject filterDone(String data) {
return DomainObject.parse(data); // no exception allowed.
}
});

Becasue of no exception allowed, we have to use following workaround.

XHR.get(url).then(new DonePipe<String, DomainObject, Throwable, Progress>() {
Promise<DomainObject, Throwable, Progress> pipeDone(String data) {
DeferredObject<> deferred = new DeferredObject<>();
try {
DomainObject obj = DomainObject.parse(data);
deferred.resolve(obj);
} catch (Throwable e) {
deferred.reject(e);
}
return deferred.
}
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.