2014-10-03 64 views
0

我有以下要執行的任務:發射2個可觀測量,處理的結果,然後發射另一個

我需要發射2個可觀測量(OBS1 & OBS2)處理其結果,然後調用另一個可觀察到的(obs3)和處理其結果,並且如果可能的話,在處理obs3的結果時可以訪問obs1和obs2的結果。

這是我的草案代碼,它沒有這樣做,我該如何改變它。

public void executeFind(String session_id, long template_id, GameModelType game_model) { 

    Observable<RxMessage<byte[]>> userObs = context.getUser(session_id); 
    Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING); 

    Observable.zip(userObs, gameObs, new Func2<RxMessage<byte[]>, Game, GameObject>() { 

    @Override 
    public GameObject call(RxMessage<byte[]> userRawReply, ActiveGame game) { 

    .. 
    .. 
    return context.updateGame(game.getGameData()) 
      .subscribe(new Action1<GameObject>() { 

       @Override 
       public void call(GameObject updateReply) { 
        .. 
        .. 

       } 
      }); 

     return userReply; 
    } 
    }); 
} 

這並沒有真正的工作 - 我可以寫一個用來.flatMap \顯式調用許多嵌套調用,這顯然是框架的使用差認購每個可測量的,但結果的代碼。

什麼是解決這個問題的正確方法?

謝謝!

編輯:

我發現這個解決方案的工作,但我還是想知道是否有一個「乾淨」的方式來實現這一目標:

public void executeFind(ReplyMessage<JsonObject> replyObj, String session_id, long template_id,  GameModelType game_model) throws CommandException { 

    rx.Observable<GameObject> userObs = context.getUser(session_id); 
    rx.Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING); 

    rx.Observable.zip(userObs, gameObs, new Func2<GameObject, Game, List<Object>>() { 

     @Override 
     public List<Object> call(GameObject userReply, Game game) { 

      User user = ...; 

      final List<Object> results = new ArrayList<Object>(3); 
      results.add(ErrorCodes.STATUS_OK); 
      results.add(user); 
      results.add(game); 


      context.updateGame(game.getGameData()).subscribe(new Action1<GameObject>() { 

       @Override 
       public void call(GameObject updateReply) { 

        ... 
       } 

      }); 


      return results; 
     } 
    }).subscribe(new Action1<List<Object>>() { 

     @Override 
     public void call(List<Object> results) { 

      int status = (int) results.get(0); 
      User user = (User) results.get(1); 
      Game game = (Game) results.get(2); 

     } 

    }); 
} 
+0

這是[不清楚](http://sscce.org/)你想達到什麼。 Zip是故意從流api中刪除的,因此可能需要重新考慮您試圖解決的問題。 – user2418306 2014-10-03 15:46:55

+0

請看看我的「編輯」 - 現在可能會更清晰。如果你有更好的解決方案..請分享.... – Shvalb 2014-10-03 16:26:47

+0

再次,對我來說,就像你有OOD問題。你ziping隨機的gameObjects和userObjects,後來突然變成了userReply。然後你得到用戶,並繼續拖延。有些東西[意思是在一起](http://en.wikipedia.org/wiki/Cohesion_(computer_science))。 – user2418306 2014-10-03 17:07:12

回答

1

我想這個代碼記住以下想法的事情。可能是map可以替換爲flatMap,如果這與您的用例有關。另請注意,我只使用了Java 8 lambda表達式語法,但爲了提高可讀性,我強烈建議您爲這些函數/操作中的每一個都提供簡單且命名方法(並將它們與方法引用一起使用),因爲它會提高代碼的可理解性(這就是我們在mockito上做的,但每個人都應該在自己的代碼庫中完成)

public void executeFind(ReplyMessage<JsonObject> reply_obj, String session_id, long template_id,  GameModelType game_model) throws CommandException { 
    Observable<GameObject> userObs = context.getUser(session_id); 
    Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING); 
    Observable.zip(userObs, gameObs, (userReply, game) -> { 
     User user = ...; 
     return GameOfUser.gameFound(game, user); 
    }).map(gou -> { 
     context.updateGame(gou.gameData()).susbcribe(...); 
     return gou; 
    }).subscribe(gou -> ...); 
} 
+0

您創建的GameOfUser就像是'遊戲'和'用戶'的包裝,它會返回一個可以被映射和訂閱的Observable。我知道了嗎? – Shvalb 2014-10-03 17:55:48

+0

是的,這是主意。仍然可以進一步探索。請注意,rxjava郵件列表也是一個很好的地方。有些人遵循SO和郵件列表。 – Brice 2014-10-04 09:44:32

+0

即將考慮您的解決方案,它不是完全不同於我所建議的,不是?我的解決方案建立一個列表並通過它來訂閱。 – Shvalb 2014-10-06 01:48:40

相關問題