Skip to content

Commit b167a0f

Browse files
Add Single.finallyDo()
1 parent 563fc3f commit b167a0f

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

src/main/java/rx/Single.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import rx.annotations.Experimental;
2222
import rx.exceptions.Exceptions;
2323
import rx.exceptions.OnErrorNotImplementedException;
24+
import rx.functions.Action0;
2425
import rx.functions.Action1;
2526
import rx.functions.Func1;
2627
import rx.functions.Func2;
@@ -33,6 +34,7 @@
3334
import rx.functions.Func9;
3435
import rx.internal.operators.OnSubscribeToObservableFuture;
3536
import rx.internal.operators.OperatorDoOnEach;
37+
import rx.internal.operators.OperatorFinally;
3638
import rx.internal.operators.OperatorMap;
3739
import rx.internal.operators.OperatorObserveOn;
3840
import rx.internal.operators.OperatorOnErrorReturn;
@@ -1898,4 +1900,25 @@ public void onNext(T t) {
18981900

18991901
return lift(new OperatorDoOnEach<T>(observer));
19001902
}
1903+
1904+
/**
1905+
* Registers an {@link Action0} to be called when this {@link Single} invokes either
1906+
* {@link SingleSubscriber#onSuccess(Object)} onSuccess} or {@link SingleSubscriber#onError onError}.
1907+
* <p>
1908+
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/finallyDo.png" alt="">
1909+
* <dl>
1910+
* <dt><b>Scheduler:</b></dt>
1911+
* <dd>{@code finallyDo} does not operate by default on a particular {@link Scheduler}.</dd>
1912+
* </dl>
1913+
*
1914+
* @param action
1915+
* an {@link Action0} to be invoked when the source {@link Single} finishes.
1916+
* @return a {@link Single} that emits the same item or error as the source {@link Single}, then invokes the
1917+
* {@link Action0}
1918+
* @see <a href="http://reactivex.io/documentation/operators/do.html">ReactiveX operators documentation: Do</a>
1919+
*/
1920+
@Experimental
1921+
public final Single<T> finallyDo(Action0 action) {
1922+
return lift(new OperatorFinally<T>(action));
1923+
}
19011924
}

src/test/java/rx/SingleTest.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,4 +648,55 @@ public void doOnSuccessShouldNotSwallowExceptionThrownByAction() {
648648

649649
verify(action).call(eq("value"));
650650
}
651+
652+
@Test
653+
public void finallyDoActionShouldBeInvokedAfterOnSuccess() {
654+
Action0 finallyAction = mock(Action0.class);
655+
656+
TestSubscriber<String> testSubscriber = new TestSubscriber<String>();
657+
658+
Single
659+
.just("value")
660+
.finallyDo(finallyAction)
661+
.subscribe(testSubscriber);
662+
663+
testSubscriber.assertValue("value");
664+
testSubscriber.assertNoErrors();
665+
666+
verify(finallyAction).call();
667+
}
668+
669+
@Test
670+
public void finallyDoActionShouldBeInvokedAfterOnError() {
671+
Action0 finallyAction = mock(Action0.class);
672+
673+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
674+
675+
Throwable error = new IllegalStateException();
676+
677+
Single
678+
.error(error)
679+
.finallyDo(finallyAction)
680+
.subscribe(testSubscriber);
681+
682+
testSubscriber.assertNoValues();
683+
testSubscriber.assertError(error);
684+
685+
verify(finallyAction).call();
686+
}
687+
688+
@Test
689+
public void finallyDoActionShouldNotBeInvokedUntilSubscriberSubscribes() {
690+
Action0 finallyAction = mock(Action0.class);
691+
692+
Single
693+
.just("value")
694+
.finallyDo(finallyAction);
695+
696+
Single
697+
.error(new IllegalStateException())
698+
.finallyDo(finallyAction);
699+
700+
verifyZeroInteractions(finallyAction);
701+
}
651702
}

0 commit comments

Comments
 (0)