gpt4 book ai didi

android - RxJava 和 Retrofit2 : Chaining dependant Observable results to return a combined pojo 'in one go'

转载 作者:行者123 更新时间:2023-11-29 01:14:47 25 4
gpt4 key购买 nike

(Android/Java 专业人士,RxJava/Lambda 新手)我正在尝试创建以下 pojo:

public class ProductCombinedPojo {
private ProductPojo product;
private List<TemplatePojo> templates;

// builder pattern...
}

哪里ProductPojo是:

public class ProductPojo {
private List<String> templateUrls; // each url returns a TemplatePojo

// lots of other stuff...
}

我有以下 Retrofit2 实现:

@GET
Observable<ProductPojo> getProduct(@Url String url);

@GET
Observable<TemplatePojo> getTemplate(@Url String url);

所以第一个Observable返回 ProductPojo ,结果列表中的 uf url 被迭代并输入到第二个 Observable获取 TemplatePojo 的列表s,最后结果全部合并成一个新的ProductCombinePojo使用构建器模式。更复杂的是,由于 MVP 框架的性质,这一切都必须在一个单一的 Func0<<Observable<ProductCombinedPojo>> 中完成。链式 RxJava 实现。

我在链的末端很难干净地获得原始 ProductPojo注入(inject)生成器。这是我的工作但丑陋的解决方案(假设 mUrlmProductApimTemplateApi 都是如上所述注入(inject)和定义的):

@Override
public Observable<ProductCombinedPojo> call() {
final ProductPojo[] aProductPojo = new ProductPojo[1]; // <------------ Ugly!
return mProductApi
.getProduct(mUrl)
.flatMapIterable(new Func1<ProductPojo, List<String>>() {
@Override
public List<String> call(ProductPojo productPojo) {
aProductPojo[0] = productPojo; // <------------ Ugly!
return productPojo.getTemplateUrls();
}
})
.flatMap(new Func1<String, Observable<TemplatePojo>>(){
@Override
public Observable<TemplatePojo> call(String templateUrl) {
return mTemplateApi.getTemplate(templateUrl);
}
})
.toList()
.map(new Func1<List<TemplatePojo>, ProductCombinedPojo>() {
@Override
public ProductCombinedPojo call(List<TemplatePojo> templatePojos) {
return ProductCombinedPojo.Builder.aProductCombinedPojo()
.product(aProductPojo[0]) // <------------ Ugly!
.templates(templatePojos)
.build();
}
});
}

我该如何重写它,这样我就不需要丑陋的 final ProductPojo[] ?经过详尽的搜索和审查这个论坛上的许多类似问题,我认为一个

Func2<ProductPojo, List<TemplatePojo>, ProductCombinedPojo>

应该插在某个地方,但我不知 Prop 体在哪里。虽然我对 Lambda 解决方案的外观很感兴趣,但正确答案将授予使用上述格式的任何解决方案。

最佳答案

问题是每一个像map这样的操作或 flatMap ,您将输入转换为新的输出。如果您不在输出中包含输入,您以后将无法访问该输入。这就是您在这里面临的问题:您希望能够访问 ProductPojo进一步向下。

您可以通过返回 Pair<ProductPojo, List<String>> 来规避此问题在你的flatMapIterable功能,但这也没有任何改善。

相反,您可以创建一个新的 Observable在你的范围内ProductPojo :

public Observable<ProductCombinedPojo> call() {
return mProductApi.getProduct(mUrl)
.flatMap(new Func1<ProductPojo, Observable<ProductCombinedPojo>>() {
@Override
public Observable<ProductCombinedPojo> call(ProductPojo productPojo) {
return combinedPojoFor(productPojo);
}
});
}

private Observable<ProductCombinedPojo> combinedPojoFor(final ProductPojo productPojo) {
return Observable.from(productPojo.getTemplateUrls())
.flatMap(new Func1<String, Observable<TemplatePojo>>() {
@Override
public Observable<TemplatePojo> call(String templateUrl) {
return mTemplateApi.getTemplate(templateUrl);
}
})
.toList()
.map(new Func1<List<TemplatePojo>, ProductCombinedPojo>() {
@Override
public ProductCombinedPojo call(List<TemplatePojo> templatePojos) {
return ProductCombinedPojo.Builder.aProductCombinedPojo()
.product(productPojo)
.templates(templatePojos)
.build();
}
});
}

使用 lambda:

public Observable<ProductCombinedPojo> call() {
return mProductApi.getProduct(mUrl)
.flatMap((productPojo) -> combinedPojoFor(productPojo));
}

private Observable<ProductCombinedPojo> combinedPojoFor(final ProductPojo productPojo) {
return Observable.from(productPojo.getTemplateUrls())
.flatMap((templateUrl) -> mTemplateApi.getTemplate(templateUrl))
.toList()
.map((templatePojos ->
ProductCombinedPojo.Builder.aProductCombinedPojo()
.product(productPojo)
.templates(templatePojos)
.build()
));
}

关于android - RxJava 和 Retrofit2 : Chaining dependant Observable results to return a combined pojo 'in one go' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40562592/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com