RxJava (12) combineLatest 연산 자의 고급 사용

전재 에 오신 것 을 환영 합 니 다. 전재 출처 를 표시 해 주 십시오.http://blog.csdn.net/johnny901114/article/details/61191723 본문 은 [여지 강의 블 로그] 에서 나 왔 다.
RxJava 시리즈 글 디 렉 터 리 안내:
1. RxJava create 연산 자의 용법 과 소스 코드 분석
2. RxJava map 연산 자 용법 상세 설명
3. RxJava flatMap 연산 자 용법 상세 설명
4. RxJava concatMap 연산 자 용법 상세 설명
5. RxJava onErrorResumeNext 연산 자 는 app 과 서버 간 token 체 제 를 실현 합 니 다.
6. RxJava retry 연산 자가 오류 재 시도 체 제 를 실현 할 때
7. RxJava 는 debounce 연산 자 를 사용 하여 app 검색 기능 을 최적화 합 니 다.
8. RxJava concat 작업 처리 다 중 데이터 원본
9. RxJava zip 연산 자가 Android 에서 의 실제 사용 장면
10. RxJava switchIfEmpty 연산 자 는 안 드 로 이 드 검사 로 컬 캐 시 논리 판단 을 실현 합 니 다.
11. RxJava defer 연산 자 는 코드 지원 체인 호출 을 실현 합 니 다.
12. combineLatest 연산 자의 고급 사용
13. RxJava 로 인해 Fragment Activity 메모리 누 출 문제
combineLatest 연산 자 는 여러 개의 Observable 이 발사 한 데 이 터 를 조립 하여 발사 하 는 데 사용 된다. Func 류 를 통 해 여러 개의 Observable 이 발사 한 데 이 터 를 조립 하여 마지막 Observable 이 발사 한 데 이 터 를 기 다 렸 다가 Func 에 보 내 조합 한 데 이 터 를 발사한다.
인터넷 상에 서 는 대부분 combineLatest 로 안 드 로 이 드 폼 의 검 사 를 하 는 것 을 보 았 는데, 아무래도 큰 인재 가 적 다 는 느낌 이 들 었 다. 만약 폼 이 모두 값 만 있 으 면 제출 단 추 를 사용 할 수 있다.
    Observable<CharSequence> etFeedbackInputObservable = RxTextView.textChanges(mEditFeedbackInput).skip(1);
    Observable<CharSequence> etFeedbackEmailObservable = RxTextView.textChanges(mEditFeedbackEmail).skip(1);
    Observable.combineLatest(etFeedbackInputObservable, etFeedbackEmailObservable, new Func2<CharSequence, CharSequence, Boolean>() {
        @Override
        public Boolean call(CharSequence charSequence, CharSequence charSequence2) {
            boolean inputValid = !TextUtils.isEmpty(charSequence);
            boolean emailValid = !TextUtils.isEmpty(charSequence2);
            return inputValid && emailValid;
        }
    }).subscribe(new Observer<Boolean>() {
        @Override
        public void onCompleted() {
            Logger.d("onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            Logger.e("onError-->" + e.toString());
        }

        @Override
        public void onNext(Boolean aBoolean) {
            //         
            mButtonSendFeedback.setEnabled(aBoolean);
        }
    });

실제 프로젝트 개발 에서 combineLatest 작업 은 간단 한 폼 검 사 를 할 수 있 을 뿐만 아니 라 더욱 복잡 한 업무 장면 도 할 수 있다. 가장 중요 한 것 은 이런 장면 을 만나면 RxJava 조작 부호 로 해결 할 수 있다 는 것 이다.
그 다음 에 회사 에 이런 업무 장면 이 있 습 니 다. 한 사용자 가 자신의 주문 목록 (이 사용 자 는 예술가 가 플랫폼 에서 예술품 을 파 는 것 입 니 다) 을 확인 해 야 합 니 다. 화면 은 주문 의 기본 정 보 를 보 여 주 는 것 외 에 Item 의 밑 에 어떤 사용자 가 구 매 했 는 지 보 여 줘 야 합 니 다 (구매자 의 얼굴 과 이름 을 보 여 줍 니 다). 그러나 배경 에서 돌아 온 JSON 데이터 에 대응 하 는 Bean 은 다음 과 같 습 니 다.
public class JsonOrderPage<Order> {
    public List<Order> data;
    public Paging paging;
}

느낌 도 별 것 아 닌 것 같 지만, 백 스테이지 로 돌아 오 는 Order 대상 에 서 는 구매자 에 대한 정 보 는 구매자 의 id 만 있 지만, 화면 에는 구매자 의 이름과 프로필 사진 이 표시 되 어야 합 니 다. 구매자 의 id 에 따라 구매자 의 정 보 를 얻어 야 합 니 다. 백 엔 드 로 돌아 오 는 것 이 List 였 으 면 좋 겠 습 니 다.그러면 flatMap 연산 자 를 사용 하여 잘 해결 할 수 있 습 니 다. 물론 가장 직관 적 인 해결 방식 은 바로 for 순서 링 입 니 다. 다음 과 같 습 니 다.
Observable<JsonOrderPage> observableUser = xxx;
observableJsonOrderPage.flatMap(new Func1<JsonOrderPage, Observable<JsonOrderPage>>() {
    @Override
    public Observable<JsonOrderPage> call(JsonOrderPage page) {
        List<Order> orders = page.getData();
        for (Order order : orders) {
            //            
            User buyer = userApi.getUserInfoById(order.getBuyer().getBuyerId());
            //            Order
            order.setBuyer(buyer);
        }
    }
})

기능 을 실 현 했 지만 기분 이 좋 지 않 습 니 다. 모두 RxJava 와 같은 강력 한 프레임 워 크 를 사 용 했 고 for 순환 으로 조작 해 야 합 니 다. 이런 수 요 를 비교적 우아 하 게 실현 할 수 있 는 방법 이 있 습 니까?
이러한 수 요 는 A 대상 의 특정한 List 속성 에 대해 RxJava 작업 을 한 다음 에 작업 결 과 를 원래 의 A 대상 에 게 다시 부여 하 는 것 이다.
우 리 는 A 대상 의 List 를 조작 하 는 것 을 알 고 있 습 니 다. RxJava 작업 을 한 후에 돌아 오 는 것 은 List 입 니 다. 원래 의 A 대상 을 얻 을 수 없습니다. 우리 가 먼저 A 대상 을 얻 은 다음 에 변 수 를 통 해 저장 하고 List 를 처리 한 후에 최종 List 를 A 대상 에 게 할당 하 는 방법 이 첫 번 째 방법 보다 못 합 니까?내 가 생각 하 는 것 은 전 과정 을 RxJava 연산 자로 하 는 방법 이 있 습 니까?
이러한 수 요 는 아직도 매우 많다. 예 를 들 어 사용자 대상 (User) 을 되 돌려 주 는 것 이다. 그 안에 List 속성 이 그의 친 구 를 나타 내 지만 친구 에 대한 정 보 는 id. 인터페이스 에 표 시 된 그의 친구 정보 만 있다.
이러한 수 요 는 데이터 의 특정한 키 데 이 터 를 단독으로 처리 해 야 합 니 다. combineLatest 를 사용 하여 우아 하 게 실현 할 수 있 습 니 다.
userApi = ApiServiceFactory.createService(UserApi.class);
//      
userApi.fetchUserInfo(null)
        .flatMap(new Func1<User, Observable<User>>() {
            @Override
            public Observable<User> call(User user) {
                printLog(tvLogs, "----fetch a user---- 
"
, getUserString(user)); return fetchFriendsInfo(user); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<User>() { @Override public void call(User user) { printLog(tvLogs, "----process his friends by id----
"
, getUserString(user)); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { throwable.printStackTrace(); } }); // private Observable<User> fetchFriendsInfo(User user) { // User Observable<User> observableUser = Observable.just(user); // User Observable<List<User>> observableUsers = Observable.from(user.getFriends()) .flatMap(new Func1<User, Observable<User>>() { @Override public Observable<User> call(User user) { // ID return userApi.fetchUserInfo(user.getId() + ""); } }) .toList(); // User . return Observable.combineLatest(observableUser, observableUsers, new Func2<User, List<User>, User>() { @Override public User call(User user, List<User> users) { user.setFriends(users); return user; } }); }

위의 코드 는 매우 간단 하고 주석 도 비교적 상세 하 다. 대체적으로 User 정 보 를 두 부분 으로 나 누 는 것 이다.
일 부 는 User 의 기본 편지 Observable<User> 이 고 일 부 는 User 친구 목록 Observable<List<User>> 이다. 그리고 두 개의 최종 데 이 터 를 조합 하 는 것 이 우리 가 최종 적 으로 필요 로 하 는 데이터 이다.
나 는 github 에 이미 관련 예 를 썼 는데, 운행 효 과 는 다음 과 같다.
본문의 예 는 github 에 놓 여 있다.https://github.com/chiclaim/android-sample/tree/master/rxjava

좋은 웹페이지 즐겨찾기