如何映射从 observable 返回的值以用于另一个 observable

how to map values returned from observable to be used in another observable

我有以下 observable 可以从数据库中获取 feed id 列表(我使用 sugar ORM 库

  public Observable<Set<Long>> getFeedIdsFromDB() {
            return Observable.create(subscriber -> {

                Set<Integer> subscribedFeedIds = new HashSet<>();

               //get feed ids from FeedEntity Table

                for (FeedEntity feed : FeedEntity.listAll(FeedEntity.class)){
                    if (feed.isSubscribed()){
                        subscribedFeedIds.add(feed.getFeedId());
                    }
                }
            });
    }

此 Observable 应发出用于以下 api 调用的 ID:

public Observable<StoryCollectionEntity> storyEntityList(final int page) {
        return this.restApi.storyCollection(/* this is feed ids*/ id, page)
                .distinct(storyCollectionEntity -> storyCollectionEntity)
                .doOnNext(saveStoryCollectionToCacheAction)

}

我想我应该使用某种映射,但不知道如何实现它。

编辑: 我做了以下修改:

// To map feed ids (retrieved from database) to getAllStoryEntityList Observable: 
@Override
    public Observable<StoryCollectionEntity> storyEntityList(final int page) {
        return this.mNewsCache.getFeedIdsFromDB().flatMap(id -> getAllStoryEntityList(page, id));
    }



//call restApi
    public Observable<StoryCollectionEntity> getAllStoryEntityList(final int page, Set<Long> id){
            return this.restApi.storyCollection( id, page)
                    .distinct(storyCollectionEntity -> storyCollectionEntity)
                    .doOnNext(saveStoryCollectionToCacheAction);
        }

但 api 服务从未被调用。映射有问题。

@GET("story")
     Observable<StoryCollectionEntity> storyCollection(
            @Query("feed_ids") Set<Long> feedIds,
            @Query("page") int page);

我不确定预期的输出是什么,但我会向您展示一种执行此类操作的方法。也许您可以更改它以适合您的用例。

第一步是允许id作为storyEntityList中的函数参数:

public Observable<StoryCollectionEntity> storyEntityList(final int page, int id) {
        return this.restApi.storyCollection(/* this is feed ids*/ id, page)
                .distinct(storyCollectionEntity -> storyCollectionEntity)
                .doOnNext(saveStoryCollectionToCacheAction)

现在您可以使用 Observable.flatMap:

public Observable<StoryCollectionEntity> getAllStoryEntityList(int page){
    return getFeedIdsFromDB().flatMap(id -> storyEntityList(page, id));
}

命名可能有误,但同样 - 我不确定实体是什么。

getFeedIdsFromDB 中创建的 Observable 没有发射任何项目,所以你的 flatMap 和其他数据转换永远不会发生,因为流实际上没有 data。您可以通过直接订阅返回的 Observable 并为 onNext 做一些事情来测试它。

getFeedIdsFromDB().subscribe(feedId -> System.out.println(feedId));

您应该会看到没有打印任何内容。当使用 Observable#create 时,匿名 class 中 subscriberonNext 方法必须用您希望传递给下游的任何数据手动调用。文档为此提供了示例代码。

所以修改你的 Observable 来调用 onNext,我们得到这个:

public Observable<Set<Long>> getFeedIdsFromDB() {
    return Observable.create(subscriber -> {
        Set<Integer> feedIds = new HashSet<>();

        // get feed ids from FeedEntity Table
        for (FeedEntity feed : FeedEntity.listAll(FeedEntity.class)){
            feedIds.add(feed.getFeedId());
        }

        // emit a single Set and complete
        if (subscriber.isSubscribed()) {
            subscriber.onNext(feedIds);
            subscriber.onCompleted();
        }
    });
}

现在 Set 应该被传递了。如果您的目标是在转换后最终发射单个 StoryCollectionEntity 对象(如果我没看错的话),那么您的映射看起来是正确的。