使用 RxJava 将一个 Observable 中的数据缝合到另一个 Observable 中
Stitch Data from One Observable into another Observable with RxJava
我有两个类型为 User
和 Image
的 Observable 流:
final Observable<List<Image>> images = mNetworkingService.getImages(getToken(context));
final Observable<List<User>> users = mNetworkingService.getUsers()
.onErrorReturn(new Func1<Throwable, List<User>>() {
@Override
public List<User> call(Throwable throwable) {
return Collections.emptyList();
}
});
我想根据图像和用户对象中包含的 userId
将用户的名字和姓氏分配给每个图像对象的 fullName
字段。
这是我目前所拥有的,但不确定 zip 是否是最佳选择。我很接近,但是当我尝试 return 图像对象的集合时出现错误,因为它期望 List 图像但认为它只是一个图像对象。如果有 better/cleaner 方法可以做到这一点 correlation/assignment 我会很感兴趣。
return Observable.zip(images, users,
new Func2<List<Image>, List<User>, Observable<List<Image>>>() {
@Override
public Observable<List<Image>> call(final List<Image> images, List<User> users) {
for (Image image : images) {
for (User user : users) {
if (image.userId.equals(user.userId)) {
image.fullName = user.getFullName();
}
}
}
return Observable.from(images); // Error: Expecting List<Image> but got Image.
}
}).flatMap(new Func1<Observable<List<Image>>, Observable<List<Image>>>() {
@Override
public Observable<List<Image>> call(Observable<List<Image>> it) {
return it;
}
});
zip() 如果您想在两个请求都完成后采取行动并获得两个结果,那么这是正确的选择。
from()
将 Iterable<T>
作为参数并将其展平为 T 的 Observable
,这意味着它将单独发出每个项目,这意味着
Observable.from(images)
returns Observable<Image>
,而您将 zipper 方法定义为 returns Observable<List<Image>>
所以存在不匹配和编译错误。
但是,无论如何,你不应该从 zipper 方法中 return Observable
,因为 zipper 只是希望你转换你要转换的多个对象得到,到单个对象。
对于 2 个项目的每个 'zip' 发射,它将执行拉链,并且您将获得 onNext()
和结果压缩对象,但在您的情况下,您将发射 Observable 对象与每个 onNext()
,这可能不是你想要的。
总而言之,您可能需要这样的东西:
Observable.zip(images, users,
new Func2<List<Image>, List<User>, List<Image>>() {
@Override
public List<Image> call(final List<Image> images, List<User> users) {
for (Image image : images) {
for (User user : users) {
if (image.userId.equals(user.userId)) {
image.fullName = user.getFullName();
}
}
}
return images;
}
})
.subscribe(new Action1<List<Image>>() {
@Override
public void call(List<Image> images) {
//do something with the list of images combined with user data
}
});
我有两个类型为 User
和 Image
的 Observable 流:
final Observable<List<Image>> images = mNetworkingService.getImages(getToken(context));
final Observable<List<User>> users = mNetworkingService.getUsers()
.onErrorReturn(new Func1<Throwable, List<User>>() {
@Override
public List<User> call(Throwable throwable) {
return Collections.emptyList();
}
});
我想根据图像和用户对象中包含的 userId
将用户的名字和姓氏分配给每个图像对象的 fullName
字段。
这是我目前所拥有的,但不确定 zip 是否是最佳选择。我很接近,但是当我尝试 return 图像对象的集合时出现错误,因为它期望 List 图像但认为它只是一个图像对象。如果有 better/cleaner 方法可以做到这一点 correlation/assignment 我会很感兴趣。
return Observable.zip(images, users,
new Func2<List<Image>, List<User>, Observable<List<Image>>>() {
@Override
public Observable<List<Image>> call(final List<Image> images, List<User> users) {
for (Image image : images) {
for (User user : users) {
if (image.userId.equals(user.userId)) {
image.fullName = user.getFullName();
}
}
}
return Observable.from(images); // Error: Expecting List<Image> but got Image.
}
}).flatMap(new Func1<Observable<List<Image>>, Observable<List<Image>>>() {
@Override
public Observable<List<Image>> call(Observable<List<Image>> it) {
return it;
}
});
zip() 如果您想在两个请求都完成后采取行动并获得两个结果,那么这是正确的选择。
from()
将 Iterable<T>
作为参数并将其展平为 T 的 Observable
,这意味着它将单独发出每个项目,这意味着
Observable.from(images)
returns Observable<Image>
,而您将 zipper 方法定义为 returns Observable<List<Image>>
所以存在不匹配和编译错误。
但是,无论如何,你不应该从 zipper 方法中 return Observable
,因为 zipper 只是希望你转换你要转换的多个对象得到,到单个对象。
对于 2 个项目的每个 'zip' 发射,它将执行拉链,并且您将获得 onNext()
和结果压缩对象,但在您的情况下,您将发射 Observable 对象与每个 onNext()
,这可能不是你想要的。
总而言之,您可能需要这样的东西:
Observable.zip(images, users,
new Func2<List<Image>, List<User>, List<Image>>() {
@Override
public List<Image> call(final List<Image> images, List<User> users) {
for (Image image : images) {
for (User user : users) {
if (image.userId.equals(user.userId)) {
image.fullName = user.getFullName();
}
}
}
return images;
}
})
.subscribe(new Action1<List<Image>>() {
@Override
public void call(List<Image> images) {
//do something with the list of images combined with user data
}
});