33

Does anybody knows what is the difference between operators "doAfterTerminate" and "doFinally" in RxJava 2 ?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Andrii Turkovskyi
  • 27,554
  • 16
  • 95
  • 105
  • Have you looked at their JavaDoc: [doAfterTerminat](http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Observable.html#doAfterTerminate-io.reactivex.functions.Action-) and [doFinally](http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Observable.html#doFinally-io.reactivex.functions.Action-)? – akarnokd Nov 15 '17 at 11:56
  • Thanks! I've looked at [docs here](http://reactivex.io/documentation/operators), but not at your links – Andrii Turkovskyi Nov 15 '17 at 12:21

1 Answers1

58

The difference is that doFinally executes the provided Action if the downstream cancels/disposes the sequence in addition to the regular onError or onComplete termination paths. This allows cleaning up and releasing resources by all three means. The operator also guarantees that the action gets executed exactly once per subscription even in case if the onError or onComplete signals race with a cancellation.

In contrast, doAfterTerminate only covers onError and onComplete.

You can emulate doFinally with doAfterTerminate + doOnCancel, however, being split a operation, the action parameters may be both executed and cause problems with non-idempotent cleanup logic.

akarnokd
  • 69,132
  • 14
  • 157
  • 192
  • After some testing it seems that doFinally() runs on the downstream scheduler, is that true or I'm missing something? – Ofek Regev May 13 '19 at 11:55
  • 1
    It runs on the scheduler that triggered the termination, which could be an upstream or downstream scheduler. There is not much you can do but have an action that uses `Schedulers.xxx().scheduleDirect` to execute the real cleanup action. – akarnokd May 13 '19 at 13:15
  • Well, I cannot access directly to the scheduler for the cleanup so in my case I cannot use scheduleDirect(). But, I just found that the operator unsubscribeOn() affect the doFinally() which is much more suitable in my case. So I have a little question, is doFinally() guaranteed to run on the scheduler assigned on unsubscribeOn()? – Ofek Regev May 13 '19 at 13:22
  • If the sequence completes normally, it runs on that scheduler instead. – akarnokd May 13 '19 at 13:59
  • So I understand that when the sequence doesn't complete normally doFinally() will not be called on the scheduler registered on unsubscibeOn(). can you explain what it means completing not normally or give me a reference to an explanation? – Ofek Regev May 13 '19 at 14:51
  • 1
    If the sequence terminates with onError or onCompleted, the upstream's thread is used to execute the action. If the sequence is disposed before that, the thread calling dispose will run the action. – akarnokd May 14 '19 at 07:05