2014-10-24 3 views
1

다른 반환 유형을 가진 스트림 \ Observables간에 작성하는 방법을 이해하는 데는 개념적으로 문제가 있습니다. 1. 방법을 .ZIP 사용하여 관찰 가능한 2 방출 :streams Observables를 올바르게 작성하는 방법

public void findSeat() { 
    rx.Observable<GameObject> userObs = context.getUser(); 
    rx.Observable<ActiveGame> gameObs = context.findGame(); 

    rx.Observable.zip(userObs, gameObs, (userObj, game) -> { 

     User user = ...; 

     final List<Object> results = new ArrayList<Object>(3); 

     if(userObj.getStatus() != ErrorCodes.STATUS_OK) { 
      results.add(-1); 
      return results; 
     } 

     ... 
     ... 

     //*********************************** 
     // THE PROBLEM IS HERE: 
     // "context.getActiveGameManager().updateGame(game)" returns Observable<GameOBject> and not List<Object> like .zip() expects. 
     // because of that I cannot do: 
     // "return context.getActiveGameManager().updateGame(game);" 
     // How can I do this convertion from Observable<GameObject> to List<Object> 
     //************************************ 

     context.getActiveGameManager().updateGame(game) 
      .map((gameObj) -> { 

       if(gameObj.getStatus() != ErrorCodes.STATUS_OK) { 
        results.add(-2); 
        return (Observable<? extends Object>) results; 
       } 

       results.add(ErrorCodes.STATUS_OK); 
       results.add(user); 
       results.add(gameObj); 
       return gameObs; 
     }); 

     return Observable.empty(); 

    }).subscribe((results) -> { 

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


     replyObj.reply(new JsonObject() 
        .putString("action", CommandActions.FIND_SEAT) 
        .putNumber("status", status); 
        .putNumber("game_id", game.getGameId()) 
       ); 

    }); 
} 

흐름은 다음과 같다 : 여기

내가 코드를 시도하고 초안 방법이다. 2. 스트림의 반환 값에 대해 일부 논리를 수행하고 결과가 error-code -> 목록에 넣고 반환하면 "subscribe"가 오류를 사용자에게 반환 할 수 있습니다. 3. 오류가 없으면 flatMap()을 사용하여 다른 "업데이트"메서드를 내 보냅니다. 여기에 문제가 있습니다. 4. 결국 모든 결과는 "구독"으로 처리되어야합니다. 사용자가 그의 요청에 대해 인정하는 지점이기 때문입니다.

는 그런데

, 나는 rxJava를 배우려고 노력하고있어 ... 충분히 분명 희망하지만 내가 충분히 \ 좋은 소스가 찾을 매우 어렵습니다 - 사람이 배울 수있는 가장 좋은 방법 나에게 추천 할 수 있습니다 그것?? 나는 Youtube, Wikipedia, Github에서 튜토리얼을보고있다. 그들 대부분은 스칼라와 다른 스크립팅 언어를 가르치고있다. 자바에서는 아무것도 찾을 수 없다.

노력 해 주신 여러분 감사합니다 !!

답변

2

나는 거의 거기에 있었지만, .zip 람다 내부의 코드를 더 작은 Rx 조작으로 분해하려고 시도했다고 생각한다. 예를 들어 :

rx.Observable 
    .zip(userObs, gameObs, (userObj, game) -> { 
     // Combine the user & game objects and pass them to the 
     // next Rx operation. 
     return new UserAndActiveGame(userObj, game); 
    }) 
    .filter(userAndActiveGame -> { 
     // Remove this filter if you want errors to make it to the subscriber. 
     return userAndActiveGame.getUserObj().getStatus() == ErrorCodes.STATUS_OK; 
    }) 
    .flatMap(userAndActiveGame -> { 
     // Remove this check if you filter errors above. 
     if (userAndActiveGame.getUserObj().getStatus() != ErrorCodes.STATUS_OK) { 
      return Observable.just(new FindSeatResult(-1)); 
     } 

     return context.getActiveGameManager().updateGame(userAndActiveGame.getGame()) 
      .map(gameObj -> { 
       if (gameObj.getStatus() != ErrorCodes.STATUS_OK) { 
        return new FindSeatResult(-2); 
       } 

       User user =...; // Whatever you are doing to get this in your example code. 
       return new FindSeatResult(ErrorCodes.STATUS_OK, user, gameObj); 
      }); 
    }) 

다음 수업은 중간 및 최종 결과를 전달하는 데 사용됩니다

private class UserAndActiveGame { 
    private final GameObject userObj; 
    private final ActiveGame game; 

    public UserAndActiveGame(GameObject userObj, ActiveGame game) { 
     this.userObj = userObj; 
     this.game = game; 
    } 

    public GameObject getUserObj() { 
     return userObj; 
    } 

    public ActiveGame getGame() { 
     return game; 
    } 
} 

private class FindSeatResult { 
    private final int status; 
    private final User user; 
    private final ActiveGame game; 

    public FindSeatResult(int status) { 
     this(status, null, null); 
    } 

    public FindSeatResult(int status, User user, ActiveGame game) { 
     this.status = status; 
     this.user = user; 
     this.game = game; 
    } 

    public User getUser() { 
     return user; 
    } 

    public int getStatus() { 
     return status; 
    } 

    public ActiveGame getGame() { 
     return game; 
    } 
} 

귀하의 가입자는 이미하고있는 것과 유사한 포장 된 결과를 사용합니다. 중간 및 최종 결과 클래스를 사용하는 대신 List<Object> 코드에 결과 주위에 전달하여

.subscribe((results) -> { 
    // You don't need this if you filter errors above. 
    if (findSeatResult.getStatus() == -1) { 
     return; 
    } 

    int status = findSeatResult.getStatus(); 
    User user = findSeatResult.getUser(); 
    ActiveGame game = findSeatResult.getGame(); 

    replyObj.reply(new JsonObject() 
       .putString("action", CommandActions.FIND_SEAT) 
       .putNumber("status", status); 
       .putNumber("game_id", game.getGameId()) 
      ); 
}); 

훨씬 더 관대 변화하고 컴파일러는 당신을 위해 모든 것을 확인 입력합니다.

+0

WOW - 답장을 보내 주셔서 감사합니다. 답장을 검토하고 있습니다. 기본적으로 이해하려고합니다. 고맙습니다!! – Shvalb

+0

이 작업을 수행하는 방법을 이해하는 데 문제가 있었기 때문에 중첩 된 .zip()을 사용하려고했으나 해결책은 완벽했습니다. 고맙습니다. – Shvalb

+0

. 필터와 관련하여 조건이 true를 반환하면> 다음 단계로 진행하고 'false'-> 무엇보다 ?? 그것은 사슬을 끊고 그게 다 ?? 사용자에게 회신을 보내기 위해 '구독'또는 '오류'방법으로 이동하는 방법이 있습니다. – Shvalb

관련 문제