Skip to content

Commit c3b6014

Browse files
Add Single.doAfterTerminate()
1 parent e6cea45 commit c3b6014

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
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;
@@ -34,6 +35,7 @@
3435
import rx.internal.operators.OnSubscribeToObservableFuture;
3536
import rx.internal.operators.OperatorDelay;
3637
import rx.internal.operators.OperatorDoOnEach;
38+
import rx.internal.operators.OperatorFinally;
3739
import rx.internal.operators.OperatorMap;
3840
import rx.internal.operators.OperatorObserveOn;
3941
import rx.internal.operators.OperatorOnErrorReturn;
@@ -1998,4 +2000,25 @@ public void call(SingleSubscriber<? super T> singleSubscriber) {
19982000
}
19992001
});
20002002
}
2003+
2004+
/**
2005+
* Registers an {@link Action0} to be called when this {@link Single} invokes either
2006+
* {@link SingleSubscriber#onSuccess(Object)} onSuccess} or {@link SingleSubscriber#onError onError}.
2007+
* <p>
2008+
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/finallyDo.png" alt="">
2009+
* <dl>
2010+
* <dt><b>Scheduler:</b></dt>
2011+
* <dd>{@code doAfterTerminate} does not operate by default on a particular {@link Scheduler}.</dd>
2012+
* </dl>
2013+
*
2014+
* @param action
2015+
* an {@link Action0} to be invoked when the source {@link Single} finishes.
2016+
* @return a {@link Single} that emits the same item or error as the source {@link Single}, then invokes the
2017+
* {@link Action0}
2018+
* @see <a href="http://reactivex.io/documentation/operators/do.html">ReactiveX operators documentation: Do</a>
2019+
*/
2020+
@Experimental
2021+
public final Single<T> doAfterTerminate(Action0 action) {
2022+
return lift(new OperatorFinally<T>(action));
2023+
}
20012024
}

src/test/java/rx/SingleTest.java

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
import rx.schedulers.Schedulers;
5151
import rx.subscriptions.Subscriptions;
5252

53-
5453
public class SingleTest {
5554

5655
@Test
@@ -828,4 +827,55 @@ public void deferShouldPassNullPointerExceptionToTheSubscriberIfSingleFactoryRet
828827

829828
verify(singleFactory).call();
830829
}
830+
831+
@Test
832+
public void doAfterTerminateActionShouldBeInvokedAfterOnSuccess() {
833+
Action0 action = mock(Action0.class);
834+
835+
TestSubscriber<String> testSubscriber = new TestSubscriber<String>();
836+
837+
Single
838+
.just("value")
839+
.doAfterTerminate(action)
840+
.subscribe(testSubscriber);
841+
842+
testSubscriber.assertValue("value");
843+
testSubscriber.assertNoErrors();
844+
845+
verify(action).call();
846+
}
847+
848+
@Test
849+
public void doAfterTerminateActionShouldBeInvokedAfterOnError() {
850+
Action0 action = mock(Action0.class);
851+
852+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
853+
854+
Throwable error = new IllegalStateException();
855+
856+
Single
857+
.error(error)
858+
.doAfterTerminate(action)
859+
.subscribe(testSubscriber);
860+
861+
testSubscriber.assertNoValues();
862+
testSubscriber.assertError(error);
863+
864+
verify(action).call();
865+
}
866+
867+
@Test
868+
public void doAfterTerminateActionShouldNotBeInvokedUntilSubscriberSubscribes() {
869+
Action0 action = mock(Action0.class);
870+
871+
Single
872+
.just("value")
873+
.doAfterTerminate(action);
874+
875+
Single
876+
.error(new IllegalStateException())
877+
.doAfterTerminate(action);
878+
879+
verifyZeroInteractions(action);
880+
}
831881
}

0 commit comments

Comments
 (0)