繁体   English   中英

rxjava2 - 如果还有可能

[英]rxjava2 - if else on Maybe

我正在寻找 rxjava2 中推荐的做法来处理一个 flowable 导致条件行为的情况。

更具体地讲,我有一个Maybe<String>了,我想更新String数据库。如果String存在,或者,如果不存在,我想创建一个新的IT 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");
         }
     });

您有 isEmpty() 运算符,如果 Maybe 源为空或不为空,它将返回您的布尔值,然后您可以对其进行 flatMap 并根据该布尔值编写 if else 语句

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

这是我们现在正在做的事情(这个例子是当 2 个选项都是 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 的操作符看起来不会太难(但我觉得我错过了一些东西)。

尝试这样的事情。 checkDB可以返回一个 Maybe 或 Single 或任何发出optional或包装对象的东西。

checkDB(String)
            .flatMap(s -> {
                if (s.isPresent()) {
                    return updateDB(s.get());
                } else {
                    return insertDB("new String");
                }
            })

有一个使用带有 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
                }
            )
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM