请查看下面的代码。我从城市检索类别的代码:
mcityAPI.authDevice(req)
.subscribeOn(Schedulers.io())
.flatMap(token -> mcityAPI.getCategories("/city/599/category",prepareHeaders(token)))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(categoryList->
{
HashMap<String, String> categoryNamesMap = new HashMap<>();
for (Category category : categoryList)
{
categoryNamesMap.put(category.getId(), category.getName());
}
}
, throwable ->
{
Throwable error = throwable;
String err = error.toString();
});
因此,首先需要授权设备 - authDevice
。然后,需要提供令牌来调用getCategories
(实际上,应该首先通过调用prepareHeaders
将令牌转换为头文件)
到目前为止,它有效。我能够成功加载类别。下一步是获取事件。在这种情况下,我应该调用/city/599/event
,但我需要这样做:
categoryName
。每个返回的事件都将包含名为categoryId
的字段。我还添加了一个额外的字段categoryName
。对于每个返回的类别,我需要为categoryName
额外字段分配适当的值。类别名称应通过categoryList
categoryId
检索
有没有任何优雅的方式(一些rxJava运算符等)允许做我想要的?
答案 0 :(得分:2)
据我所知,你的令牌是每台设备所以你可以存储它以便以后使用它。
首先:
其次:
现在,您可以在同一个流中发出两个请求。
请记住正确使用subscribeOn
。它仅在上游和observeOn
下游工作。这意味着您要求MainTread
,因此您应该更改它。
您可以使用operator map来获取categoriesMap;
您应该注意错误处理,因为一次失败会取消订阅您的信息流,因此无法再次使用。
triggerSubject
.flatMap(token -> mcityAPI.getCategories("/city/599/category",prepareHeaders(sharedPreferences.getToken())))
.map(categoryList -> {
final HashMap<String, String> categoryNamesMap = new HashMap<>();
for (Category category : categoryList)
{
categoryNamesMap.put(category.getId(), category.getName());
}
return categoryNamesMap;
})
.flatMap(cateogyrNameMap -> yourApiCall, prepareHeaders(sharedPreferences.getToken()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry()
.subscribe(event -> {
// Do what you need
}
, throwable ->
{
Throwable error = throwable;
String err = error.toString();
});
答案 1 :(得分:1)
你可以复制第一部分,再次平面图并将两个观察者与Zip operator
结合起来但它在性能方面表现不佳
您可以做的是使用相同的令牌observable来触发这两个请求。因此,通过将第一个Observable<Token>
转换为热的可观察对象,您可以在不启动请求两次的情况下使用它:
Observable<Token> obsToken = mcityAPI.authDevice(req)
.share(); // So the authDevice method is only invoqued once
// Assumming your Category's ID is an Integer
Observable<Map<Integer, Category>> obsCategories = obsToken
.flatMap(token -> mcityAPI.getCategories("/city/599/category",prepareHeaders(token)))
.toList() // So we have all categories
.map(categoryList -> {
Map<Integer, Category> result = new HashMap<>();
for (Category c : categories)
result.put(c.getId(), c);
return result;
})
.subscribeOn(Schedulers.io());
Observable<List<Event>> obsEvents = obsToken
.flatMap(token -> mcityAPI.getEvents("/city/599/eventprepareHeaders(token)))
.toList() // So we have all events
.subscribeOn(Schedulers.io());
Observable<?> result = Observable.zip(obsCategories, obsEvents, (categories, events) -> {
// now you have all categories and events
// you can now fill category name by looking into the first map
for (Event e : events)
events.forEach(event ->
event.setCategoryName(
categories.get(event.getCategoryId()).getName()
)
);
// Do the rest of mapping and return something...
}