使用 RxJava 更新依赖于另外两个 API 响应的对象列表

Update List of objects that is dependent on two other API responses with RxJava

所以,基本上我有一个需要更新的对象列表。为了更新每个对象,我需要调用 2 个相关的 API 调用,这些调用最终将 return 数据(在本例中是用户头像)。

这就是我想要做的:

private Observable<List<User>> fetchFileInfo(List<User> userList) {
    return Observable.fromIterable(userList)
            .concatMap((Function<User, ObservableSource<FileData>>) user -> fetchFileInfoById(user.getId()))
            .concatMap((Function<FileData, ObservableSource<String>>) fileData -> fetchAvatarUrl(fileData.getEntityId()))
            .concatMap((Function<String, ObservableSource<User>>) avatarUrl -> ???)
            .toList()
            .toObservable();
}

private Observable<FileData> fetchFileInfoById(int id) {
    return getApiService()
            .getFileInfo(id)
            .map(fileDataResponseWrapper -> fileDataResponseWrapper.getData().get(0));
}

private Observable<String> fetchAvatarUrl(int entityId) {
    return getApiService()
            .getFile(entityId)
            .map(responseBodyResponse -> responseBodyResponse.raw().request().url().toString());
}

所以,我首先为每个用户获取文件,然后获取该文件信息的头像。但是,如何使用收到的头像更新每个对象?

创建嵌套的 rx 链:

return Observable.fromIterable(userList)
    .concatMap(user -> {
        return fetchFileInfoById(user.getId())
            .concatMap(fileData -> fetchAvatarUrl(fileData.getEntityId()))
            .concatMap(avatarUrl -> getUpdatedUser(user, avatarUrl))
    })
    .toList()
    .toObservable();

您可以在内链中引用user实例。

第二个选项是像这个例子一样创建包装器:

private Observable<List<User>> fetchFileInfo(List<User> userList) {
    return Observable.fromIterable(userList)
            .concatMap((Function<User, ObservableSource<Pair>>) user -> new Pair(user, fetchFileInfoById(user.getId())))
            .concatMap((Function<Pair, ObservableSource<Triple>>) pair -> new Triple(pair.user, pair.fileData, fetchAvatarUrl(pair.fileData.getEntityId())))
            .concatMap((Function<Triple, ObservableSource<User>>) triple -> getUpdatedUser(triple.user, triple.avatarUrl))
            .toList()
            .toObservable();
}



class Pair {
    User user;
    FileData fileData;
}

class Triple {
    User user;
    FileData fileData;
    String avatarUrl;
}