Skip to content

Commit

Permalink
Provide aliases for filter/pipe. Fix for jdeferred#165
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmiray committed Mar 19, 2018
1 parent 2db9cde commit 1edd07e
Show file tree
Hide file tree
Showing 6 changed files with 719 additions and 148 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ If you are using JDeferred 1.x, see [JDeferred 1.x Documentation](http://jdeferr
* 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(…)```
Expand Down Expand Up @@ -113,7 +116,7 @@ deferred.notify("100%");
```java
Deferred d = …;
Promise p = d.promise();
Promise filtered = p.then(new DoneFilter<Integer, Integer>() {
Promise filtered = p.filter(new DoneFilter<Integer, Integer>() {
public Integer filterDone(Integer result)
return result * 10;
}
Expand All @@ -137,7 +140,7 @@ d.resolve(3) -> 30.
Deferred d = ...;
Promise p = d.promise();

p.then(new DonePipe<Integer, Integer, Exception, Void>() {
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);
Expand Down
178 changes: 178 additions & 0 deletions subprojects/jdeferred-core/src/main/java/org/jdeferred2/Promise.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,77 @@ <D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> then(
FailFilter<? super F, ? extends F_OUT> failFilter,
ProgressFilter<? super P, ? extends P_OUT> progressFilter);

/**
* Equivalent to {@code filter(doneFilter, null, null)}
*
* @see #filter(DoneFilter, FailFilter, ProgressFilter)
* @param doneFilter the filter to execute when a result is available
* @return a new promise for the filtered result
*/
<D_OUT> Promise<D_OUT, F, P> filter(DoneFilter<? super D, ? extends D_OUT> doneFilter);

/**
* Equivalent to {@code filter(doneFilter, failFilter, null)}
*
* @see #filter(DoneFilter, FailFilter, ProgressFilter)
* @param doneFilter the filter to execute when a result is available
* @param failFilter the filter to execute when a failure is available
* @return a new promise for the filtered result and failure.
*/
<D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> filter(
DoneFilter<? super D, ? extends D_OUT> doneFilter,
FailFilter<? super F, ? extends F_OUT> failFilter);

/**
* This method will register filters such that when a Deferred object is either
* resolved ({@link Deferred#resolve(Object)}), rejected ({@link Deferred#reject(Object)}) or
* is notified of progress ({@link Deferred#notify(Object)}), the corresponding filter
* will be invoked. The result of the filter will be used to invoke the same action on the
* returned promise.
*
* {@link DoneFilter} and {@link FailFilter} will be triggered at the time the Deferred object is
* resolved or rejected. If the Deferred object is already resolved or rejected the filter is
* triggered immediately.
*
* Filters allow to transform the outcome of a promise into something else. This concept is equivalent
* to the map() method of the java stream API.
*
* If any of the filter is not specified ({@code null}), a default No Op filter is used.
* If your filter is returning a {@link Promise} consider using {@link #pipe(DonePipe, FailPipe, ProgressPipe)}.
*
* <pre>
* <code>
* Deferred deferred = new DeferredObject();
* Promise promise = deferred.promise();
* Promise filtered = promise.filter(new DoneFilter<Integer, Integer>() {
* Integer filterDone(Integer result) {
* return result * 10;
* }
* });
*
* filtered.then(new DoneCallback<Integer>() {
* void onDone(Integer result) {
* System.out.println(result);
* }
* });
*
* deferred.resolve(1); // prints 10
* </code>
* </pre>
*
* @param doneFilter the filter to execute when a result is available.
* If {@code null}, use {@link org.jdeferred2.impl.FilteredPromise.NoOpDoneFilter}
* @param failFilter the filter to execute when a failure is available.
* If {@code null}, use {@link org.jdeferred2.impl.FilteredPromise.NoOpFailFilter}
* @param progressFilter the filter to execute when progress info is available.
* If {@code null}, use {@link org.jdeferred2.impl.FilteredPromise.NoOpProgressFilter}
* @return a new promise for the filtered result, failure and progress.
*/
<D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> filter(
DoneFilter<? super D, ? extends D_OUT> doneFilter,
FailFilter<? super F, ? extends F_OUT> failFilter,
ProgressFilter<? super P, ? extends P_OUT> progressFilter);

/**
* Equivalent to {#code then(DonePipe, null, null)}
*
Expand Down Expand Up @@ -270,6 +341,75 @@ <D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> then(
FailPipe<? super F, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> failPipe,
ProgressPipe<? super P, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> progressPipe);

/**
* Equivalent to {#code pipe(DonePipe, null, null)}
*
* @see #pipe(DonePipe, FailPipe, ProgressPipe)
* @param donePipe the pipe to invoke when a result is available
* @return a new promise for the piped result.
*/
<D_OUT> Promise<D_OUT, F, P> pipe(DonePipe<? super D, ? extends D_OUT, ? extends F, ? extends P> donePipe);

/**
* Equivalent to {@code pipe(DonePipe, FailPipe, null)}
*
* @see #pipe(DonePipe, FailPipe, ProgressPipe)
* @param donePipe the pipe to invoke when a result is available
* @param failPipe the pipe to invoke when a failure is available
* @return a new promise for the piped result and failure.
*/
<D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> pipe(
DonePipe<? super D, ? extends D_OUT, ? extends F_OUT, ? extends P> donePipe,
FailPipe<? super F, ? extends D_OUT, ? extends F_OUT, ? extends P> failPipe);

/**
* This method will register pipes such that when a Deferred object is either
* resolved ({@link Deferred#resolve(Object)}), rejected ({@link Deferred#reject(Object)}) or
* is notified of progress ({@link Deferred#notify(Object)}), the corresponding pipe
* will be invoked.
*
* {@link DonePipe} and {@link FailPipe} will be triggered at the time the Deferred object is
* resolved or rejected. If the Deferred object is already resolved or rejected the filter is
* triggered immediately.
*
* This method is similar to JQuery's pipe() method, where a new {@link Promise} is returned
* by the the pipe filter instead of the original. This is useful to handle return values
* and then rewiring it to different callbacks.
*
* Pipes start a new {@link Deferred} object. This allows to chain asynchronous calls.
*
* If your pipe does not do any asynchronous work consider using {@link #filter(DoneFilter, FailFilter, ProgressFilter)}
*
* <pre>
* <code>
* promise.pipe(new DonePipe<Integer, Integer, String, Void>() {
* {@literal @}Override
* Deferred<Integer, Void, Void> pipeDone(Integer result) {
* // Reject values greater than 100
* if (result > 100) {
* return new DeferredObject<Integer, Void, Void>().reject("Failed");
* } else {
* return new DeferredObject<Integer, Void, Void>().resolve(result);
* }
* }
* }).done(...)
* .fail(...);
* </code>
* </pre>
*
* @param donePipe the pipe to invoke when a result is available.
* If {@code null}, result is piped unchanged
* @param failPipe the pipe to invoke when a failure is available.
* If {@code null}, failure is piped unchanged
* @param progressPipe the pipe to execute when progress info is available.
* If {@code null}, progress is piped unchanged
* @return a new promise for the piped result, failure and progress.
*/
<D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> pipe(
DonePipe<? super D, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> donePipe,
FailPipe<? super F, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> failPipe,
ProgressPipe<? super P, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> progressPipe);

/**
* This method will register a pipe such that when a Deferred object is either
* resolved ({@link Deferred#resolve(Object)}) or rejected ({@link Deferred#reject(Object)})
Expand Down Expand Up @@ -308,6 +448,44 @@ <D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> then(
<D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> always(
AlwaysPipe<? super D, ? super F, ? extends D_OUT, ? extends F_OUT, ? extends P> alwaysPipe);

/**
* This method will register a pipe such that when a Deferred object is either
* resolved ({@link Deferred#resolve(Object)}) or rejected ({@link Deferred#reject(Object)})
* the pipe will be invoked.
*
* {@link AlwaysPipe} will be triggered at the time the Deferred object is
* resolved or rejected. If the Deferred object is already resolved or rejected the filter is
* triggered immediately.
*
* This method is similar to JQuery's pipe() method, where a new {@link Promise} is returned
* by the the pipe filter instead of the original. This is useful to handle return values
* and then rewiring it to different callbacks.
*
* Pipes start a new {@link Deferred} object. This allows to chain asynchronous calls.
*
* <pre>
* <code>
* promise.alwaysPipe(new pipeAlways<Integer, Integer, String, String, Void>() {
* {@literal @}Override
* Promise<Integer, Void, Void> pipeAlways(State state, Integer resolved, Integer rejected) {
* if (state == State.RESOLVED) {
* return new DeferredObject<String, String, Void>().resolve("Success");
* } else {
* return new DeferredObject<String, String, Void>().reject("Failed");
* }
* }
* }).done(...)
* .fail(...);
* </code>
* </pre>
*
* @since 2.0
* @param alwaysPipe the pipe to invoke when a result or failure is available.
* @return a new promise for the piped result or failure.
*/
<D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> pipeAlways(
AlwaysPipe<? super D, ? super F, ? extends D_OUT, ? extends F_OUT, ? extends P> alwaysPipe);

/**
* This method will register {@link DoneCallback} so that when a Deferred object
* is resolved ({@link Deferred#resolve(Object)}), {@link DoneCallback} will be triggered.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,25 @@ public <D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> then(
return new FilteredPromise<D, F, P, D_OUT, F_OUT, P_OUT>(this, doneFilter, failFilter, progressFilter);
}

@Override
public <D_OUT> Promise<D_OUT, F, P> filter(
DoneFilter<? super D, ? extends D_OUT> doneFilter) {
return new FilteredPromise<D, F, P, D_OUT, F, P>(this, doneFilter, null, null);
}

@Override
public <D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> filter(
DoneFilter<? super D, ? extends D_OUT> doneFilter, FailFilter<? super F, ? extends F_OUT> failFilter) {
return new FilteredPromise<D, F, P, D_OUT, F_OUT, P>(this, doneFilter, failFilter, null);
}

@Override
public <D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> filter(
DoneFilter<? super D, ? extends D_OUT> doneFilter, FailFilter<? super F, ? extends F_OUT> failFilter,
ProgressFilter<? super P, ? extends P_OUT> progressFilter) {
return new FilteredPromise<D, F, P, D_OUT, F_OUT, P_OUT>(this, doneFilter, failFilter, progressFilter);
}

@Override
public <D_OUT> Promise<D_OUT, F, P> then(
DonePipe<? super D, ? extends D_OUT, ? extends F, ? extends P> doneFilter) {
Expand All @@ -224,11 +243,37 @@ public <D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> then(
return new PipedPromise<D, F, P, D_OUT, F_OUT, P_OUT>(this, doneFilter, failFilter, progressFilter);
}

@Override
public <D_OUT> Promise<D_OUT, F, P> pipe(
DonePipe<? super D, ? extends D_OUT, ? extends F, ? extends P> doneFilter) {
return new PipedPromise<D, F, P, D_OUT, F, P>(this, doneFilter, null, null);
}

@Override
public <D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> pipe(
DonePipe<? super D, ? extends D_OUT, ? extends F_OUT, ? extends P> doneFilter,
FailPipe<? super F, ? extends D_OUT, ? extends F_OUT, ? extends P> failFilter) {
return new PipedPromise<D, F, P, D_OUT, F_OUT, P>(this, doneFilter, failFilter, null);
}

@Override
public <D_OUT, F_OUT, P_OUT> Promise<D_OUT, F_OUT, P_OUT> pipe(
DonePipe<? super D, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> doneFilter,
FailPipe<? super F, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> failFilter,
ProgressPipe<? super P, ? extends D_OUT, ? extends F_OUT, ? extends P_OUT> progressFilter) {
return new PipedPromise<D, F, P, D_OUT, F_OUT, P_OUT>(this, doneFilter, failFilter, progressFilter);
}

@Override
public <D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> always(AlwaysPipe<? super D, ? super F, ? extends D_OUT, ? extends F_OUT, ? extends P> alwaysFilter) {
return new PipedPromise<D, F, P, D_OUT, F_OUT, P>(this, alwaysFilter);
}

@Override
public <D_OUT, F_OUT> Promise<D_OUT, F_OUT, P> pipeAlways(AlwaysPipe<? super D, ? super F, ? extends D_OUT, ? extends F_OUT, ? extends P> alwaysFilter) {
return new PipedPromise<D, F, P, D_OUT, F_OUT, P>(this, alwaysFilter);
}

@Override
public boolean isPending() {
return state == State.PENDING;
Expand Down

0 comments on commit 1edd07e

Please sign in to comment.