rxjava2 - 如果在Maybe上的话

时间:2017-11-03 12:50:58

标签: java rx-java2

我正在寻找rxjava2中推荐的做法,以处理一个可流动导致条件行为的情况。

更具体地说,我有一个Maybe<String>,如果String存在,我想要更新数据库上的String,或者如果它不存在我想要创建一个新的String并将其保存在数据库中。

我想到了下面但很明显它不是我想要的:

Maybe<String> source = Maybe.just(new String("foo")); //oversimplified source
source.switchIfEmpty(Maybe.just(new String("bar"))).subscribe(result -> 
System.out.println("save to database "+result));
source.subscribe(result -> System.out.println("update result "+result));

以上显然会产生

save to database foo
update result foo

我也试过下面给出了预期的结果,但仍觉得它很奇怪。

Maybe<String> source = Maybe.just(new String("foo")); //oversimplified source
source.switchIfEmpty(Maybe.just(new String("bar")).doOnSuccess(result -> 
System.out.println("save to database "+result))).subscribe();
source.doOnSuccess(result -> System.out.println("update result "+result)).subscribe();

如何在结果存在以及何时不存在时执行操作?该用例应该如何在rxjava2中处理?

更新01

我尝试了下面的内容,它看起来比我上面提到的更干净。请注意,建议使用rxjava2练习...

Maybe.just(new String("foo"))
     .map(value -> Optional.of(value))
     .defaultIfEmpty(Optional.empty())
     .subscribe(result -> {
         if(result.isPresent()) {
             System.out.println("update result "+result);
         }
         else {
             System.out.println("save to database "+"bar");
         }
     });

4 个答案:

答案 0 :(得分:1)

如果Maybe源为空,你有isEmpty()运算符将返回Boolean,然后你可以flatMap它并根据布尔值写一个if else语句

答案 1 :(得分:1)

这也是我们代码中的常见模式,但在我们的例子中,选择本身就是异步的。通过简单地组合flatMapX和switchIfEmpty(以任何顺序),你无法获得非常正确的语义,所以我很好奇为什么这不是API的一部分。

以下是我们现在正在做的事情(这个示例表示当两个选项都是Completables时,我们对其他类型也有类似的东西):

public static <T> Completable flatMapCompletable(Maybe<T> target, 
                                                 @ClosureParams(FirstParam.FirstGenericType.class) 
                                                         Closure<? extends CompletableSource> completableSupplier, 
                                                 Supplier<CompletableSource> emptySupplier) {
    Maybe<T> result = target.cache();
    return result.isEmpty().flatMapCompletable(empty -> {
       if (empty) {
           return emptySupplier.get();
       } else {
           return result.flatMapCompletable(completableSupplier::call);
       }
    });
}

我们正在使用Groovy,因此我们将它们打包为扩展方法。我对使用cache()的需要感到兴奋,所以我想知道是否有更好的选择。通过查看代码,基本上将flatMapX和switch组合在一起的运算符看起来不会太难(但我觉得我错过了一些东西)。

答案 2 :(得分:0)

尝试这样的事情。 optional可以返回Maybe或Single或发出checkDB(String) .flatMap(s -> { if (s.isPresent()) { return updateDB(s.get()); } else { return insertDB("new String"); } }) 或包装器对象的任何内容。

$line = $code . ";" . $name . ";" . $email . PHP_EOL;

答案 3 :(得分:0)

有一个使用带有 3 个参数的 flatMap 调用的解决方案

fun addOrUpdate(message: LocalMessage): Single<LocalMessage> {
        return getById(message.id) // returns Maybe
            .flatMap(
                Function {
                    update(message) // onSuccess update call returns Single
                },
                Function {
                    Single.error(it) // onError
                },
                Callable {
                    add(message) // onComplete add call returns Single
                }
            )
    }
}

或更短的版本

fun addOrUpdate(message: LocalMessage): Single<LocalMessage> {
        return getById(message.id) // returns Maybe
            .flatMap(
                {
                    update(message) // onSuccess update call returns Single
                },
                {
                    Single.error(it) // onError
                },
                {
                    add(message) // onComplete add call returns Single
                }
            )
    }
}