2017-04-01 23 views
5

Tôi đang cố di chuyển từ RxJava1 sang RxJava2. Tôi đang thay thế tất cả các phần mã mà trước đó tôi đã có Observable<Void> đến Compleatable. Tuy nhiên, tôi đã gặp phải một sự cố với thứ tự các cuộc gọi luồng. Khi tôi trước đây đã được giao dịch với Observables và sử dụng bản đồ và flatMaps mã làm việc 'như mong đợi'. Tuy nhiên, toán tử andthen() dường như hoạt động hơi khác một chút. Đây là một mã mẫu để đơn giản hóa vấn đề.Thứ tự dãy RxJava2 được gọi với toán tử tương ứng và sau đó

public Single<String> getString() { 
    Log.d("Starting flow..") 
    return getCompletable().andThen(getSingle()); 
} 

public Completable getCompletable() { 
    Log.d("calling getCompletable"); 
    return Completable.create(e -> { 
       Log.d("doing actuall completable work"); 
       e.onComplete(); 
      } 
    ); 
} 

public Single<String> getSingle() { 
    Log.d("calling getSingle"); 
    if(conditionBasedOnActualCompletableWork) { 
     return getSingleA(); 
    }else{ 
     return getSingleB(); 
    } 
} 

Những gì tôi nhìn thấy trong các bản ghi cuối cùng là:

1-> Log.d("Starting flow..") 
    2-> Log.d("calling getCompletable"); 
    3-> Log.d("calling getSingle"); 
    4-> Log.d("doing actuall completable work"); 

Và như bạn có lẽ có thể tìm ra tôi mong chờ dòng 4 để được gọi trước khi dòng 3 (sau đó tên của andthen() điều hành gợi ý rằng mã sẽ được gọi là 'after' Hoàn thành xong công việc của nó). Trước đây tôi đã tạo Observable<Void> bằng cách sử dụng toán tử Async.toAsync() và phương pháp hiện được gọi là getSingle là trong luồng flatMap - nó hoạt động như tôi mong đợi, vì vậy Log 4 sẽ xuất hiện trước 3. Bây giờ tôi đã thử thay đổi cách tạo ra Compleatable - như sử dụng fromAction hoặc fromCallable nhưng nó hoạt động giống nhau. Tôi cũng không thể tìm thấy bất kỳ nhà điều hành nào khác để thay thế andthen(). Để gạch dưới - phương thức phải là Hoàn toàn vì nó không có ý nghĩa gì để trả về - nó thay đổi tùy chọn ứng dụng và các cài đặt khác (và được sử dụng như thế trên toàn cầu hầu hết hoạt động như mong đợi) và những thay đổi đó là cần thiết sau trong luồng. Tôi cũng đã cố gắng để bọc getSingle() phương pháp bằng cách nào đó tạo ra một đơn và di chuyển các tuyên bố nếu bên trong khối tạo nhưng tôi không biết làm thế nào để sử dụng phương pháp getSingleA/B() bên trong đó. Và tôi cần phải sử dụng chúng vì chúng có độ phức tạp của riêng chúng và nó không có ý nghĩa để sao chép mã. Bất kỳ ai có bất kỳ ý tưởng làm thế nào để sửa đổi này trong RxJava2 do đó, nó cư xử như nhau? Có nhiều nơi mà tôi dựa vào một công việc có thể cạnh tranh để hoàn thành trước khi tiến lên phía trước với luồng (như mã thông báo phiên làm mới, cập nhật db, tùy chọn, v.v. - không có vấn đề trong RxJava1 sử dụng flatMap).

+0

Bạn có hiểu rằng việc gọi 'getSingle()' thực thi ngay lập tức và không sau khi 'Hoàn thành' được trả về bởi' getCompletable' đã hoàn tất? – akarnokd

Trả lời

1

Bạn có thể sử dụng Hoãn:

getCompletable().andThen(Single.defer(() -> getSingle())) 

Bằng cách đó, bạn không thực hiện các nội dung của getSingle() ngay lập tức nhưng chỉ khi Completable hoàn thành và andThen chuyển sang các Single.

+0

Cảm ơn bạn về mẹo, tôi đã đánh dấu câu trả lời là hữu ích - nó giải quyết được vấn đề. Mặc dù tôi phải nói nó trông giống như một giải pháp workaround. Tôi vẫn còn khá bối rối tại sao các hành vi thay đổi so với phiên bản RxJava1, nơi tôi sử dụng flatMap và callbacks theo thứ tự tôi mong đợi họ. Đã không tìm thấy bất kỳ thông tin nào về nó trong phần 'có gì mới' của tài liệu RxJava2. –

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