我想知道如何使用RxJava2执行以下操作,
我对RxJava很新,并尝试使用Single
进行初始API调用,然后使用map
运算符,然后在Mapper函数中,然后用其他内容完成正常的外环和内环。
我真的很想知道映射器函数部分是否也能以某种方式以更简单的方式使用RxJava而不是使用嵌套循环?
答案 0 :(得分:0)
您的外部循环可能如下所示:
Observable.fromIterable( list )
.flatMap( item -> checkItemAndReplace( item ) )
.toList();
并且内部循环可以是:
Observable<ItemType> checkItemAndReplace( ItemType item ) {
if ( isItemOfSpecificType( item ) ) {
return getUpdatesForItem( item );
}
return Observable.just( item );
}
内循环等等。我把事情分解为返回observables的嵌套函数调用,但是你可以将它们重新组合成一个可观察的链,这取决于你的代码风格和测试需求。
需要注意的要点:
fromIterable()
和just()
转换为observable,而toList()
转换回列表。map()
;当需要将observable转换为它产生的值时,请使用flatMap()
。答案 1 :(得分:0)
查看 Api 界面和 itemsToBeRefreshed Observable。您可以使用 Observable.fromIterable 来迭代列表和 flatMap 来链接不同的api调用。此外,如果您有请求 - 响应行为,则应使用Single作为返回类型。此外,不要更改流中项目的属性。只需将要更改的项目复制到新对象中并将其写回。
@Test
public void name() throws Exception {
Api api = mock(Api.class);
when(api.getItems()).thenReturn(Single.just(Arrays.asList(
new Item(0, 123),
new Item(1, 123),
new Item(2, 333)
)));
when(api.getUserDetails(eq(0))).thenReturn(Single.just(new UserDetails("hans wurst", 0)));
when(api.getUserDetails(eq(1))).thenReturn(Single.just(new UserDetails("mett wurst", 1)));
when(api.getUserDetails(eq(2))).thenReturn(Single.just(new UserDetails("kaese wurst", 2)));
when(api.getData(eq(0), eq("hans wurst"))).thenReturn(Single.just(new Data(123)));
when(api.getData(eq(1), eq("mett wurst"))).thenReturn(Single.just(new Data(123)));
when(api.getData(eq(2), eq("kaese wurst"))).thenReturn(Single.just(new Data(666)));
Observable<Item> itemsToBeRefreshed = api.getItems()
.flatMapObservable(strings -> Observable.fromIterable(strings))
.filter(s -> s instanceof Item) // test for specific type
.flatMapMaybe(item -> api.getUserDetails(item.id)
.flatMap(userDetails -> api.getData(userDetails.id, userDetails.userName))
.filter(data -> data.code == item.code)
.map(data -> new Item(-1, -1)) // create new Item and copy properties over from data
);
itemsToBeRefreshed.test()
.assertValueCount(2);
// subscribe to 'itemsToBeRefreshed' in order to write back items or just chain it to itemsToBeRefreshed with doOnNext
}
interface Api {
Single<List<Item>> getItems();
Single<UserDetails> getUserDetails(int id);
Single<Data> getData(int id, String userName);
}
class Item {
int id;
int code;
Item(int id, int code) {
this.id = id;
this.code = code;
}
}
class UserDetails {
String userName;
int id;
UserDetails(String userName, int id) {
this.userName = userName;
this.id = id;
}
}
class Data {
int code;
Data(int code) {
this.code = code;
}
}