RxJava - 调用Observables方法时的非确定性行为

时间:2015-04-29 15:43:59

标签: java rx-java

我遇到以下代码的问题:

public void foo(List<Player> players_list) {

    JsonArray playersArr = new JsonArray();

    rx.Observable.from(players_list) // assume players_list is a list contains 2 players
    .concatMap(player -> {

    return getUser(player.getUserId()) // get entity 'User' from DB
    .flatMap(userObj -> {
        User user = ...;

        playersArr.add(new JsonObject()
            .putString("uid", player.getExtUserId())
        );

            return rx.Observable.just(playersArr);
        });
    }).subscribe(playersObj -> {

    }, (exception) -> {
        log.error("", exception);

    }, () -> {

        // at this point I expect 'playersArr' to consist 2 entries!
    });
}

运行此代码时,它的输出似乎是非确定性的,这意味着 - 大多数时候我在JsonArray中得到2个条目的有效结果,但有时我得到1个条目。

我想找出原因??

修改
我尝试从.flatMap切换 - &gt; .concatMap似乎解决了这个问题,但我不确定它真的是一个很好的解决方案。

1 个答案:

答案 0 :(得分:2)

我将假设playerArrs不是线程安全的,如果您的Observable在异步上下文中执行,则playerArrs可能会跳过添加调用。

您的Observable有一些副作用,您是否更新了Observable之外的对象。为避免这种情况,您可以通过Observable构建JsonArray

的方式更新代码
public void foo(List<Player> players_list) {

    rx.Observable.from(players_list) // assume players_list is a list contains 2 players
                 .concatMap(player -> getUser(player.getUserId()) // get entity 'User' from DB
                 .map(userObj -> new JsonObject().putString("uid", player.getExtUserId())
                .reduce(new JsonArray(), (seed, acu) -> seed.add(acu))) // build the JsonArray
                .subscribe(playersObj -> { }, 
                           (exception) -> { log.error("", exception); }, 
                          () -> {
    // at this point I expect 'playersArr' to consist 2 entries!
                 });
}

我不确定我的代码,但我认为它应该接近你需要的代码。