简体   繁体   English

rxjava2 - 如果还有可能

[英]rxjava2 - if else on Maybe

I am looking for what is the recommended practice in rxjava2 to handle a case where one flowable leads to conditional behaviors.我正在寻找 rxjava2 中推荐的做法来处理一个 flowable 导致条件行为的情况。

More concretely, I have a Maybe<String> for which I want to Update the String on the database if the String exists or, if it doesn't exists I want to create a new String and save it on the database.更具体地讲,我有一个Maybe<String>了,我想更新String数据库。如果String存在,或者,如果不存在,我想创建一个新的IT String ,并将其保存在数据库中。

I thought of the below but obviously it is not what I am looking for:我想到了以下内容,但显然这不是我要找的:

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));

The above obviously produces以上显然产生

save to database foo
update result foo

I tried also the below which gives the expected result but still feel it's... weird.我也尝试了下面的方法,它给出了预期的结果,但仍然觉得它......很奇怪。

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();

How can I have an action for when the result exists and when it doesn't exists?当结果存在和不存在时,我如何才能采取行动? How is that use case supposed to be handled in rxjava2?应该如何在 rxjava2 中处理该用例?

Update 01更新 01

I tried the below and it looks cleaner than what I came up with above.我尝试了下面的方法,它看起来比我上面提出的更清晰。 Note sure it is recommended rxjava2 practice however...请注意确保建议使用 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 语句

This is a common pattern in our code as well, though in our case the choices are themselves async.这也是我们代码中的常见模式,尽管在我们的例子中选择本身是异步的。 You can't get quite the right semantic by simply composing flatMapX and switchIfEmpty (in either order), so I am curious why this isn't part of the API.您不能通过简单地组合 flatMapX 和 switchIfEmpty(以任一顺序)来获得完全正确的语义,所以我很好奇为什么这不是 API 的一部分。

Here's what we're doing for now (this example for when the 2 options are both Completables, we have similar things for the other types as well):这是我们现在正在做的事情(这个例子是当 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);
       }
    });
}

We're using Groovy, so we package these up as extension methods.我们正在使用 Groovy,因此我们将它们打包为扩展方法。 I'm not thrilled with the need to use cache() so I'm wondering if there is a better alternative.我对使用cache()的需要并不感到兴奋,所以我想知道是否有更好的选择。 From looking at the code, an operator which basically combines flatMapX and switch looks like it wouldn't be too hard (but I feel like I'm missing something).从代码来看,一个基本上结合了 flatMapX 和 switch 的操作符看起来不会太难(但我觉得我错过了一些东西)。

Try something like this.尝试这样的事情。 checkDB can return a Maybe or Single or whatever which emits either an optional or a wrapper Object. checkDB可以返回一个 Maybe 或 Single 或任何发出optional或包装对象的东西。

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

There is an solution using the flatMap call with 3 params有一个使用带有 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
                }
            )
    }
}

Or shorter version或者更短的版本

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