RxJava - 将flatMap运算符转发到链中的后续点

问题描述 投票:1回答:3

我正在开发一种汽车牌游戏,它允许你创建一个帐户并拥有一些汽车卡。基本上,服务器上的每个新创建的帐户都已拥有一些卡。在下面的代码中,我正在创建一个帐户,并使用自有汽车的ID将其保存在数据库中。

private Observable<Account> createAccount() {
    return AccountService.createAccount()
            .flatMap(account -> persistAccount(account))
            .flatMap(account -> persistOwnedCarsFromServer(account));
}

private Observable<Account> persistAccount(final Account account) {
    ... persist account ...
    return Observable.just(account);
}

private Observable<Account> persistOwnedCars(final Account account) {
    return AccountService.getOwnedCarIds()
            .flatMap(carIds -> persistOwnedCarIds(account.mId, carIds))
            .flatMap(carsIds -> Observable.just(account)); // don't like this line
}

private Observable<List<Integer>> persistOwnedCarIds(final int accountId, final List<Integer> ownedCarIds){
    ... persist car ids together with accountId ...
    return return Observable.just(ownedCarIds);
}

我对这段代码的问题是persistOwnedCars()的最后一行。我宁愿删除这一行,让该方法返回一个Observable<List<Integer>>作为结果,所以我也可以在其他地方使用它。所以实际上我想在createAccount()方法中实现这样的东西:

private Observable<Account> createAccount() {
    return AccountService.createAccount()
            .flatMap(account -> persistAccount(account)) // returns Observable<Account>
            .flatMap(account -> persistOwnedCarsFromServer(account)) // returns Observable<List<Integer>>
            .magic(carIds -> returnAccountFromAbove()); // returns Observable<Account> 
}

有没有办法以某种方式将flatMap operator的结果转发到链中的后一点?或者是否有更好的方法来实现这一切?谢谢!

rx-java rx-android
3个回答
2
投票

如评论中所述,您最好的选择是将结果映射回帐户类型,如果您以后需要帐户和列表,可能需要通过Pair类的帮助:

AccountService.createAccount()
   .flatMap(account -> persistAccount(account))
   .flatMap(account -> 
        persistOwnedCarsFromServer(account).map(v -> Pair.of(account, v)) 
   .flatMap(pair -> processList(pair.second).map(v -> v.first));

1
投票

看起来你正在做副作用。我猜想persistX是一种I / O操作,通常被视为副作用。你有没有考虑过在这里使用doOnNext?如果您不更改account本身但仅使用此对象中的数据写入数据库,文件或其他任何内容然后返回相同的对象,这可能会对您有所帮助。这可能对persistAccount以及persistOwnedCars都有用。

AccountService.createAccount()
    .doOnNext(account -> persistAccount(account))
    .doOnNext(account -> persistOwnedCars(account));

private void persistAccount(final Account account) {
    // write to database
    // ...
}

// other methods like persistOwnedCars and persistOwnedCarIds here...

0
投票

当我在RxSwift中遇到类似的问题时,我从vzsg得到了这个。

getFoo().flatMap { foo in
    getBars(ofFoo: foo.id).map { bars in (foo, bars) }
}
© www.soinside.com 2019 - 2024. All rights reserved.