В RxJava, как передать переменную вместе при цепочке наблюдаемых?
Я связываю асинхронные операции с помощью RxJava, и я хотел бы передать некоторую переменную вниз по течению:
Observable
.from(modifications)
.flatmap( (data1) -> { return op1(data1); })
...
.flatmap( (data2) -> {
// How to access data1 here ?
return op2(data2);
})
это похоже на общий шаблон, но я не мог найти информацию об этом.
6 ответов:
совет, который я получил от форума Couchbase, заключается в использовании вложенных наблюдаемых:
Observable .from(modifications) .flatmap( (data1) -> { return op1(data1) ... .flatmap( (data2) -> { // I can access data1 here return op2(data2); }) });
EDIT: я отмечу это как принятый ответ, поскольку он кажется наиболее рекомендуемым. Если ваша обработка слишком сложна, чтобы вложить все, что вы можете также проверить решение с помощью вызовов функций.
еще одна возможность-сопоставить результат
op1
доorg.apache.commons.lang3.tuple.Pair
, который содержит переменную и передать:Observable .from(modifications) .flatmap( (data1) -> { return op1(data1).map( obj -> { return Pair.of(data1,obj); }); }) ... .flatmap( (dataPair) -> { // data1 is dataPair.getLeft() return op2(dataPair.getRight()); })
это работает, но он чувствует себя немного неудобно иметь переменные, скрытые внутри пары/тройной/... и он становится очень подробным, если вы используете нотацию Java 6.
интересно, есть ли лучшее решение, может быть, какой-нибудь оператор RxJava может помочь?
одной из возможностей было бы использовать вызов функции:
private static Observable<T> myFunc(final Object data1) { return op1(data1) ... .flatmap( (data2) -> { // I can access data1 here return op2(data2); }); } Observable .from(modifications) .flatmap( (data1) -> { return myFunc(data1); })
но: поправьте меня, если я ошибаюсь, но это не похоже на способ реактивного программирования
решение в этом потоке работает, но для сложных цепочек это затрудняет чтение кода, мне пришлось передать несколько значений, и то, что я сделал, это создать частный класс со всеми параметрами, я нахожу код более читаемым таким образом,
private class CommonData{ private string data1; private string data2; *getters and setters* } ... final CommonData data = new CommonData(); Observable .from(modifications) .flatmap( (data1) -> { data.setData1(data1); return op1(data1); }) ... .flatmap( (data2) -> { data2 = data.getData1() + "data 2... "; data.setData2(data2); return op2(data2); })
надеюсь, что это помогает
flatmap может занять второй arg:
Observable.just("foo") .flatMap(foo -> Observable.range(1, 5), Pair::of) .subscribe(pair -> System.out.println("Result: " + pair.getFirst() + " Foo: " + pair.getSecond()));
вы можете использовать "глобальную" переменную, чтобы достичь этого:
Object[] data1Wrapper = new Object[]{null}; Object[] data2Wrapper = new Object[]{null}; Observable .from(modifications) .flatmap(data1 -> { data1Wrapper[0] = data1; return op1(data1) }) ... .flatmap(data2 -> { // I can access data1 here use data1Wrapper[0] Object data1 = data1Wrapper[0]; data2Wrapper[0] = data2; return op2(data2); })