RxJava2:需要帮助将java代码转换为rx

时间:2018-04-04 19:58:56

标签: java android rx-java2

我是RxJava的新手,需要帮助来改进我的代码。这就是我所做的:

public Single<List<MenuItemsBlocks>> loadMenuItemsBlocks() {

    Completable.fromAction(() -> DataStoreRepository.deleteMenuItemsBlock())
            .subscribeOn(Schedulers.io()).blockingAwait();

    List<MenuItemsBlocks> blocks = new ArrayList<>();
    Set<String> aliasList = getAliasFromMenuItems();

    for (String alias : aliasList) {
        List<MenuItemsBlocks> itemsBlocks = ApiRepository.getMenuItemBlocks(alias)
                .subscribeOn(Schedulers.io())
                .flatMapIterable(list -> list)
                .map(item -> new MenuItemsBlocks(
                        item.getId(),
                        item.getType(),
                        item.getImagePosition(),
                        item.getTextField(),
                        item.getSortOrder(),
                        item.getFileTimeStamp(),
                        alias
                ))
                .doOnNext(block -> DataStoreRepository.saveMenuItemsBlock(block))
                .subscribeOn(Schedulers.io())
                .toList()
                .blockingGet();

        blocks.addAll(itemsBlocks);
    }

    return Single.just(blocks);
}

使用此代码在运行时没有问题,但我希望以rx风格改进它,我试图将其改写为类似的东西(但它不起作用):

public Single<List<MenuItemsBlocks>> loadMenuItemsBlocks() {

    Completable.fromAction(() -> DataStoreRepository.deleteMenuItemsBlock())
            .subscribeOn(Schedulers.io()).blockingAwait();

    Set<String> aliasList = getAliasFromMenuItems();

    return Observable.fromIterable(aliasList)
            .switchMap(alias -> ApiRepository.getMenuItemBlocks(alias)
                    .subscribeOn(Schedulers.io())
                    .flatMapIterable(list -> list)
                    .map(item -> new MenuItemsBlocks(
                            item.getId(),
                            item.getType(),
                            item.getImagePosition(),
                            item.getTextField(),
                            item.getSortOrder(),
                            item.getFileTimeStamp(),
                            alias
                    ))
                    .doOnNext(block -> DataStoreRepository.saveMenuItemsBlock(block))
                    .subscribeOn(Schedulers.io())
                    .toList()
            );
}

我坚持下去,需要你的帮助!

1 个答案:

答案 0 :(得分:2)

首先,如果您在非测试代码中有blockingAwait,那么您做错了。其次,您可能需要concatMap而不是switchMap,因为它会不断切换到以后的列表元素,取消未完成的API调用。

public Single<List<MenuItemsBlocks>> loadMenuItemsBlocks() {

    return Completable.fromAction(() -> DataStoreRepository.deleteMenuItemsBlock())
        .subscribeOn(Schedulers.io())
        .andThen(Single.defer(() -> {
            Set<String> aliasList = getAliasFromMenuItems();

            return Observable.fromIterable(aliasList)
                .concatMap(alias -> ApiRepository.getMenuItemBlocks(alias)
                    .subscribeOn(Schedulers.io())
                    .flatMapIterable(list -> list)
                    .map(item -> new MenuItemsBlocks(
                        item.getId(),
                        item.getType(),
                        item.getImagePosition(),
                        item.getTextField(),
                        item.getSortOrder(),
                        item.getFileTimeStamp(),
                        alias
                    ))
                    .doOnNext(block -> DataStoreRepository.saveMenuItemsBlock(block))
                    .subscribeOn(Schedulers.io())
                )
                .toList();
      }));
}