【问题标题】:RxJava - making two calls where the first one is conditionalRxJava - 在第一个是有条件的情况下进行两次调用
【发布时间】:2018-10-08 08:44:08
【问题描述】:

我正在使用 RxJava 2 进行 API 调用。 我必须打电话取消课程的预订。

但我必须先打一个电话才能获得丢失的信息。

是这样的:

if classId not exists
   get classId
   then unbook class
else
   unbook class

我不想重复取消预订课程代码。

这里是简化的代码:

FitnessDataService service = RetrofitInstance.getRetrofitInstance().create(FitnessDataService.class);
        // if we don't have the aid of class (reserved), we get it from the reserved classes


        if (fitClass.getAid() == null) {
            service.getReservedClasses(FitHelper.clientId)
                    .flatMap(reservedClasses ->
                    {
                        // get the class ID from reserved classes
                         ...
                        return service.unbookClass(fitClass.getAid());
                    }).subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(response -> {
                                // success
                            }, err -> 
                                // error
        } else {
            service.unbookClass(fitClass.getAid())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(response -> {
                                // success
                            }, err -> 
                                // error
        }

如您所见,service.unbookClass 是重复的。 如果我没有类 ID(fitClass.getAid() == null),我如何始终调用这个 service.unbookClass 并且只调用 service.getReservedClasses 无需将代码重复到第二次调用。

【问题讨论】:

    标签: java android retrofit rx-java2


    【解决方案1】:

    我建议将 id 的实际来源分离到它自己单独的 observable 中。可能是这样的:

    Observable<Long> idObservable;
    if (fitClass.getAid() == null) {
        idObservable = service.getReservedClasses(FitHelper.clientId)
            .map({ reservedClasses ->
                /* Get the Id and do stuff with it */
                return fitClass.getAid();
            });
    } else {
        idObservable = Observable.just(fitClass.getAid());
    }
    
    idObservable.flatMap({ aid -> service.unbookClass(aid) })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(/* TODO */);
    

    【讨论】:

    • 我已经实现了这个并且运行良好。谢谢 :) 刚刚将 .map 更改为 .flatMap 因为我只想从 reservedClasses 列表中获取一个值。
    【解决方案2】:

    MaybeswitchIfEmpty 看起来很适合。 fromCallable 方法如果返回值非空,则返回 1 值,如果返回的项是 null,则完成。如果源没有发出项目,switchIfEmpty 可用于提供替代(在这种情况下为 Single 或 Maybe)。假设您对 unbookClass 的改造调用返回一个单,您的代码将类似于 --

    Maybe.fromCallable(() -> fitClass.getAid())
        .switchIfEmpty(service.getReservedClasses(FitHelper.clientId)
                        .flatMap(reservedClasses -> {
                            // ....
                            return fitClass.getAid());
                        }))
        .flatMap(id -> service.unbookClass(id))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(...);
    

    【讨论】:

    • 感谢您让我了解 Maybe 运算符和 switchIfEmpty。虽然,我在实现这一点时遇到了一些麻烦。我对unbookClass 的改造调用返回了一个 Observable (Observable&lt;ArrayList&lt;FitStatus&gt;&gt;)。适应起来简单吗?
    • 是的,只需在您的改造界面中返回Single&lt;ArrayList&lt;FitStatus&gt;&gt;。大多数改造调用只返回一个元素,然后调用onComplete,这与Single相同
    • 谢谢。我将改造调用更改为返回Maybe,这样,这种方法效果很好。我认为我还可以继续使用Observable,而不是使用.singleElement() 转换为Maybe
    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多