0

my question is similar to AndThen executes before completable finished

    getLicensePlateObservable(plateNumber)
                .flatMapCompletable {
                    licensePlateId = it.id
                    getRemoveLicensePlateCompletable(licensePlateId)
                }
                .andThen(getNotifyCompletable(email, licensePlateId))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({

getLicensePlateObservable makes a network request to fetch a LicensePlate. I expected it to fetch the LicensePlate, store the id into a member var licensePlateId and remove the license plate. Then the owner with member var email should be notified about the removal.

What actually occurs is getNotifyCompletable is executed before getRemoveLicensePlateCompletable. Why did this occur and how can I make it run serially? Thanks in advance.

HukeLau_DABA
  • 2,384
  • 6
  • 33
  • 51
  • 2
    https://stackoverflow.com/questions/48624863/rxjava-completable-andthen-is-not-executing-serially – Sarath Kn Sep 13 '19 at 05:25
  • Possible duplicate of [RxJava \`Completable.andThen\` is not executing serially?](https://stackoverflow.com/questions/48624863/rxjava-completable-andthen-is-not-executing-serially) – Progman Sep 14 '19 at 11:04

1 Answers1

0

The getNotifyCompletable will be executed before getRemoveLicensePlateCompletable but completable inside getNotifyCompletable will be executed after getRemoveLicensePlateCompletable. You can see it in example:

fun main() {
    Completable.fromRunnable {
        Thread.sleep(1000)
        println("finish")
    }
        .andThen(createCompletable("1"))
        .subscribe()
}

fun createCompletable(payload: String): Completable {
    println("create $payload")
    return Completable.fromRunnable {
        println("start $payload")
        Thread.sleep(1000)
        println("end $payload")
    }
}

// will print
// create 1
// finish
// start 1
// end 1

so if you want use data from getRemoveLicensePlateCompletable in getNotifyCompletable you can use solution proposed by Sarath Kn:

getLicensePlateObservable(plateNumber)
    .flatMapCompletable {
        licensePlateId = it.id
        getRemoveLicensePlateCompletable(licensePlateId)
    }
    .andThen(Completable.defer { getNotifyCompletable(email, licensePlateId) })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({

or you can pass licensePlateId explicitly without temporary field:

getLicensePlateObservable(plateNumber)
    .flatMapSingle {
        getRemoveLicensePlateCompletable(it.id).toSingle { it.id }
    }
    .flatMapCompletable { getNotifyCompletable(email, it) }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({
Andrei Tanana
  • 7,932
  • 1
  • 27
  • 36