在另一个Observable中订阅一个Observable

时间:2018-07-03 08:54:52

标签: java rx-java reactivex

我正在调试我的代码,该代码从数据库中获取UserWallet,然后通过与外部REST API连接来为其生成地址。现在,我有一个嵌套在另一个订阅中的订阅,但是我读到它是一个不好的解决方案(它实际上不起作用,我认为这就是原因)。

userWalletDao.getUnregisteredUserWallets()
                .subscribe(nextWallet -> {
                    log.info("Fetched next wallet for registration {}", nextWallet);
                    blockchainIntegration.registerUserWallet(nextWallet.getUserId())
                            .subscribe(address -> {
                                nextWallet.setAddress(address);
                                userWalletDao.persistUserWalletAddress(nextWallet);
                                log.info("Registered wallet {} with address {}.", nextWallet, address);
                            });
                });

我试图一次订阅,但是如果我将FlatMap钱包转移到地址,则会丢失一个UserWallet对象来为其设置获取的地址并将其保存回数据库中。

如何获取钱包,然后通过一个订阅调用API为其生成地址?

getUnregisteredUserWallets()返回Observable<UserWallet>,而registerUserWallet()返回Single<String>

1 个答案:

答案 0 :(得分:1)

强烈建议您阅读并理解第一条评论中提到的相关子流。

您可以通过将可观察的顺序更改为类似的方式来解决问题

       userWalletDao.getUnregisteredUserWallets()
                .flatMap(nextWallet -> registerUserWallet(nextWallet.getUserId()).toObservable()
                        .flatMap(address -> Observable.fromCallable(() -> new Pair<>(nextWallet, address))))  // return both wallet from previous mapping and address from current mapping to the next level
                .flatMapCompletable(walletAddressPair -> Completable.fromAction(()->{
                    Wallet nextWallet = walletAddressPair.first;
                    String address = walletAddressPair.second;
                    nextWallet.setAddress(address);
                    userWalletDao.persistUserWalletAddress(nextWallet);
                    log.info("Registered wallet {} with address {}.", nextWallet, address);
                    // here wallet and address have been saved to db. This operation is a completable action, you don't have to return any result 
                    // from it and forward to the next level.  Thats why flatMapCompletable is used.
                }))
                .subscribeWith(new DisposableCompletableObserver() {
                    @Override
                    public void onComplete() {
                       // All actions completed
                    }

                    @Override
                    public void onError(Throwable e) {
                      // any error occurred in the observable chain
                    }
                });