我有两个名为A<'ModelA'>的观察者。和B<'ModelB'>。它们中的每一个都对不同的REST服务执行请求,因此它们扩展了如上所述的不同模型。任何人执行的请求都可能失败。现在,我需要能够链接它们并返回一个ModelC对象。所以,伪编码流将是这样的:
A< 'MODELA' >执行请求,如果失败则执行某些操作,如果没有则将其结果(responseModelA)传递给B<'ModelB'>所以它可以执行另一个REST请求,涉及使用responseModelA的一部分。如果B失败会发生某种情况,如果没有,则将其响应(responseModelB)与responseModelA(手动设置POJO字段)组合在一起以创建ModelC,这是订户应该在其 call()方法。
使用rxJava可以远程编码吗?我非常坚持这一点,所以我对任何消息都持开放态度。
感谢。
答案 0 :(得分: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;
}
}
要使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);
}
});
}
});
}
您的订阅者将如下所示:
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.
}
});
答案 1 :(得分:1)
顺序组合在Rx.NET中由SelectMany
实现(我认为它在Rx.Java中是FlatMap
)。 Rx.NET也适用于快速失败的语义,因此SelectMany
可能就是您所需要的。
(C#)
IObservable<ModelC> query = A().FlatMap(B, (a, b) => C(a, b));
query.Subscribe(success => DoSomethingSuccessful(), error => DoSomethingElse(error));
其中A
和B
是返回observables的函数,C
是返回ModelC的函数。
但是,如果您想在A或B失败时执行某些特定操作,那么Rx.NET中的快速解决方案是使用Do
运算符。
IObservable<ModelC> query = A().Do(_ => {}, AFailed)
.FlatMap(B.Do(_ => {}, BFailed), (a, b) => C(a, b));
query.Subscribe(success => DoSomethingSuccessful(), UltimateFailure);
其中AFailed
和BFailed
是返回void的方法,接受单个Exception
参数。
抱歉,我不了解Java,但也许这会引导您找到正确的解决方案。