我正在寻找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中处理?
我尝试了下面的内容,它看起来比我上面提到的更干净。请注意,建议使用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");
}
});
答案 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
}
)
}
}