我应该如何处理RxJava中的副作用?

时间:2016-02-04 23:53:53

标签: rx-java

我有一个Observable,它发出一个特定的对象S.这个对象内部有一个对象列表,每个对象都包含一组值。我需要将此数据平放(将所有内部集合展开为一系列平面对象A),如果它尚未存在则将其存储在数据库中,然后将对象A的序列减少回到对象T与起始对象S类似的结构,我需要传递它。

我认为在函数之外改变状态不是一个好主意,所以把它写成像这样的一个大的Observable转换是不行的(特别是因为在第二个映射中还有一个阻塞数据库调用): / p>

sObservable
    .map(turnSIntoAFn)     // <-- Actually more complex
    .map(a -> {
         store(a);
         return a;
    })
    .map(turnAIntoTFn)     // <-- Actually more complex
    .subscribe(...);

然后我想我应该将我的副作用限制在订阅者身上。这将使我遇到以下任何一种情况:

  • 将Observable转换为Observable,然后订阅将这些A抛出到数据库中的订阅者。然后查询数据库,在Observable中获取A(对于MongoDB的Rx驱动程序而言),将它们转换为T&并传递它们(与订阅者一起)

  • 使用源Observable,同时做两件事:

    1. 与上一步一样,将其转换为Observable并将A存储在数据库中。
    2. 将Observable直接转换为Observable,并乐观地传递它。

目前,第一个选项看起来更具吸引力,但它需要比脏版本和第二个替代版本更多的数据库操作。有没有更好的方法来做这种事情(做一些有用的数据,然后传递它),既不会对资源造成更大的压力,也不会改变我职能之外的状态?

2 个答案:

答案 0 :(得分:4)

您应该考虑使用the do operators - 在这种情况下,doOnNext()

doOn[Next/Error/Completed]就像是可以放在序列中的小副作用订阅。它不是转换的一部分(因为它们无法转换数据)。

答案 1 :(得分:1)

我更喜欢使用其他运算符,例如concatMap()switchMap()(它们之间的差异是另一个主题)。特别是如果您在某些数据库中具有store(a)操作(例如SQL)。

doOn[Next/Error/Completed]-是异步回调,它们的最佳用例是一些操作,例如在UI进度栏上显示/隐藏。