链接两个Observable返回另一个

mra*_*ski 2 java reactive-programming rx-java retrofit

我有两个名为A <'ModelA'>和B <'ModelB'>的可观察对象.它们中的每一个都对不同的REST服务执行请求,因此它们扩展了如上所述的不同模型.任何人执行的请求都可能失败.现在,我需要能够链接它们并返回一个ModelC对象.所以,伪编码流将是这样的:

一个<'ModelA'>执行请求,如果失败则执行某些操作,如果没有则将其结果(responseModelA)传递给B <'ModelB'>,这样它就可以执行另一个涉及使用responseModelA部分的REST请求.如果B失败会发生某些事情,如果没有,则将其响应(responseModelB)与responseModelA(手动设置POJO字段)组合在一起以创建ModelC,这是订户应该在其call()方法上接收的参数.

使用rxJava可以远程编码吗?我完全坚持这一点,所以我对任何吸烟都持开放态度.

谢谢.

kjo*_*nes 5

这假设您已经创建了一个REST请求接口,该接口返回类似于以下内容的Observable(使用Retrofit这非常简单):

interface RestApi {
    Observable<ModelA> getModelA();
    Observable<ModelB> getModelB(int modelBId);
}

class ModelA {
    int modelBId;
    Object fieldA;
}

class ModelB {
    Object fieldB;
}

class ModelC {
    Object fieldFromA;
    Object fieldFromB;

    public ModelC(Object fieldFromA, Object fieldFromB) {
        this.fieldFromA = fieldFromA;
        this.fieldFromB = fieldFromB;
    }
}
Run Code Online (Sandbox Code Playgroud)

要使ModelB请求取决于ModelA请求的结果,可以使用.flatMap将一个Observable的结果转换为另一个Observable.

然后,要创建ModelC,请使用.map从ModelA和ModelB中选择所需的字段并返回结果.

RestApi restApi;

Observable<ModelC> observeModelC() {
    return restApi
            .getModelA()
            .flatMap(new Func1<ModelA, Observable<ModelC>>() {
                @Override
                public Observable<ModelC> call(final ModelA modelA) {
                    // Use the modelBId from modelA to get ModelB.
                    return restApi
                            .getModelB(modelA.modelBId)
                            // Combine A & B to create C
                            .map(new Func1<ModelB, ModelC>() {
                                @Override
                                public ModelC call(ModelB modelB) {
                                    return new ModelC(modelA.fieldA, modelB.fieldB);
                                }
                            });
                }
            });
}
Run Code Online (Sandbox Code Playgroud)

您的订阅者将如下所示:

observeModelC()
        .subscribe(new Observer<ModelC>() {
            @Override
            public void onCompleted() {
                // All done.
            }

            @Override
            public void onError(Throwable e) {
                // All errors from any API request will end up here.
                // For Retrofit, cast e to RetrofitError for
                // detailed error info.
            }

            @Override
            public void onNext(ModelC modelC) {
                // Yeah! - Use modelC.
            }
        });
Run Code Online (Sandbox Code Playgroud)

  • 这可以简化为直接从A + B创建`ModelC`而不是通过中间`CombinedModelAB`. (2认同)