RXAndroid better way to write nested subscriptions

wheresmycookie

I'm working with an RXBle library for Android. In order to read from a BLE peripheral (BLE device) I end up setting up a number of subscribes, all within one another, like this:

    Disposable scanSubscription = null;

    public void startScan() {
        scanSubscription = rxBleClient
            .scanBleDevices(settings, filter)
            .take(1)
            .subscribe(
                scanResult -> connectDevice(scanResult.getBleDevice()),
                throwable -> {}
            );
    }

    public void connectDevice(RxBleDevice device) {
        device
            .establishConnection(false)
            .subscribe(
                connection -> requestMtu(connection),
                throwable -> {}
            );
    }

    public void requestMtu(final RxBleConnection connection) {
        connection
            .requestMtu(185)
            .subscribe(
                mtu -> readCharacteristic(connection),
                throwable -> {}
            );
    }

    public void readCharacteristic(final RxBleConnection connection) {
        /* this one eventually scanSubscription.dispose!!!!! */
    }

Essentially, I have a series of functions that perform an action on a thing, and then subscribe to the resulting Single (I think I'm using the terminology correctly)

My question is, what is a better way to write this?

Even more importantly, what happens to the nested subscribes that I never unsubscribe from? Note that in the first function I'm calling a take(1)...eventually I just dispose the top-level disposable that is calling all of this.

idunnololz

No. That is not the RX way. I recommend giving this a quick read.

The tl;dr is that you want to lay your code out so that it flows like a stream. One of the things that Rx tries to address is to eliminate nested callbacks. This "stream" approach does that.

Now onto what you can do to make it better. Here is one approach to rewriting your code so that it's a stream instead of a group of nested callbacks:

Disposable scanSubscription = null;

public void doThing() {
    scanSubscription = rxBleClient
        .scanBleDevices(settings, filter)
        .take(1)
        .map(scanResult -> scanResult.establishConnection(false))
        .map(connection -> connection.requestMtu(185))
        .map(mtu -> <do thing>)
        .subscribe(/* do things with final value */)
}

Here is another approach:

Disposable scanSubscription = null;

public void doThing() {
    scanSubscription = rxBleClient
        .scanBleDevices(settings, filter)
        .take(1)
        .flatMap(scanResult -> scanResult.establishConnection(false))
        .flatMap(connection -> connection.requestMtu(185).map(result -> Pair(connection, result)))
        .flatMap(result -> {
            Connection c = result.first;
            Mtu mtu = result.second;
            //do thing
        })
        .subscribe(/* do things with final value */)
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related