RXAndroid лучший способ написания вложенных подписок - PullRequest
0 голосов
/ 09 октября 2018

Я работаю с библиотекой RXBle для Android.Для чтения с периферийного устройства BLE (устройства BLE) я в конечном итоге настраиваю количество подписок, все в пределах друг друга, например:

    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!!!!! */
    }

По сути, у меня есть ряд функций, которые выполняютдействие на вещь, а затем подписаться на полученный сингл (я думаю, что я правильно использую терминологию)

Мой вопрос: как лучше написать это?

Еще большеважно, что происходит с вложенными подписками, от которых я никогда не отписываюсь?Обратите внимание, что в первой функции я вызываю take (1) ... в конце концов, я просто располагаю одноразовым объектом верхнего уровня, который вызывает все это.

1 Ответ

0 голосов
/ 09 октября 2018

Нет.Это не способ RX.Я рекомендую дать это краткое чтение .

TL; dr - это то, что вы хотите выложить свой код так, чтобы он тек как поток.Одна из вещей, которую пытается решить Rx, - это исключить вложенные обратные вызовы.Этот «потоковый» подход делает это.

Теперь о том, что вы можете сделать, чтобы сделать его лучше.Вот один из подходов к переписыванию вашего кода таким образом, чтобы он представлял собой поток вместо группы вложенных обратных вызовов:

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 */)
}

Вот еще один подход:

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 */)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...