2017-03-07 16 views
8

Sự cố tôi gặp phải là vấn đề này. Tôi cần phải thực hiện vài yêu cầu đến máy chủ. Mỗi yêu cầu tiếp theo phụ thuộc vào kết quả của lần trước. Họ trông như thế này (viết tắt):RxJava - Yêu cầu chuỗi và cập nhật giao diện người dùng

Observable<FileUploadResponse> obsFile = api.uploadFile(); 
Observable<TokenCreateResponse> obsCreateToken = api.createToken(); 
Observable<PaymentResponse> obsPayment = api.submitOrder(); 

tôi đã tạo ra một quan sát đơn sử dụng một flatMap mà trả về đối tượng PaymentResponse hoặc phát ra onerror() nếu một số trong những yêu cầu không được đáp ứng. Điều này làm việc tốt và tôi nhận được tất cả các yêu cầu được thực hiện trong một cuộc gọi duy nhất.

Vấn đề là tôi không thể cập nhật giao diện người dùng giữa các yêu cầu này. Với thiết lập hiện tại, tôi hiển thị quá trình tải khi yêu cầu bắt đầu và ẩn khi tất cả yêu cầu hoàn tất. Có cách nào để cập nhật giao diện người dùng ở giữa các yêu cầu này không?

Điều tôi muốn là: 1. Tải lên tệp - viết thư trên giao diện người dùng. 2. Tạo mã thông báo - viết tin nhắn trên giao diện người dùng. 3. Gửi đơn đặt hàng - viết một tin nhắn trên giao diện người dùng. 4. Khi tất cả đã hoàn tất, hãy ẩn hộp thoại tiến trình.

Sự hiểu biết của tôi sẽ phát ra một số Có thể quan sát bằng cách sử dụng onNext() khi mỗi cuộc gọi API kết thúc và sau đó gọi onComplete() khi tất cả được thực hiện. Nhưng làm thế nào để tôi làm điều này?

+0

Bạn có thể sử dụng phương thức 'doOnNext()' ở bất kỳ đâu trong đường ống xử lý của bạn để xem điều gì đang xảy ra và kết quả trung gian là gì và tất nhiên là người quan sát và ghi vào chủ đề tương ứng – Raghunandan

+0

trình bao bọc phổ biến mà bạn sẽ sử dụng làm loại của 'Người đăng ký'. Một cái gì đó như 'api.uploadFile(). FlatMap (fileUploadResponse -> Observable.concat (Observable.just (new StatusUpdate (fileUploadResponse)), api.createToken()). FlatMap (tokenCreateResponse -> Observable.concat (Observable.just (mới) StatusUpdate (tokenCreateResponse), api.submitOrder()) ... '- một thư viện được gọi là [RxSealedUnions] (https://github.com/pakoito/RxSealedUnions) là hữu ích cho một cách tiếp cận như vậy ... –

Trả lời

8

Bạn có thể đạt được điều này với doOnNextPublishSubject. Đầu tiên tạo ra một chủ ngữ và một số giá trị:

public static final int STATUS_UPLOADING = 0; 
public static final int STATUS_TOKEN = 1; 
public static final int STATUS_SUBMITTING = 2; 
public static final int STATUS_DONE = 3; 

PublishSubject<Integer> status = PublishSubject.create(); 

public Observable<Integer> getStatusStream() { 
    return status; 
} 

Sau đó, khi bạn đang làm việc upload của bạn chỉ cần gửi giá trị đến chủ đề mỗi lần:

status.onNext(STATUS_UPLOADING); 

return api.uploadFile() 
    .doOnNext(o -> status.onNext(STATUS_TOKEN)) 
    .flatMap(o -> api.createToken()) 
    .doOnNext(o -> status.onNext(STATUS_SUBMITTING)) 
    .flatMap(o -> api.submitOrder()) 
    .doOnNext(o -> status.onNext(STATUS_DONE)) 

Sau đó, bạn có thể đăng ký Subject và cập nhật UI của bạn:

model.getStatusStream() 
    .subscribeOn(AndroidSchedulers.mainThread()) 
    .subscribe(
     status -> { 
      view().setMessage(status); 
     }, 
     Throwable.printStackTrace 
    ); 

Ngoài ra tùy thuộc vào cách bạn muốn kiến ​​trúc sư ứng dụng của bạn, bạn có thể chỉ cần gọi các cuộc gọi cập nhật nhìn từ doOnNext mỗi thời gian. Có thể bạn cần phải sử dụng observeOn để chuyển đổi giữa chủ đề chính & mỗi lần.

+0

Cảm ơn, điều này là chính xác những gì tôi đang tìm kiếm. –

Các vấn đề liên quan