2015-05-14 20 views
10

Tôi đang sử dụng trang bị thêm và tôi cảm thấy như rxjava (với retrolambda) sẽ là một sự phù hợp tốt cho các dòng sau đây:Sử dụng RxJava và trang bị thêm để lặp qua danh sách và làm tăng thêm kết quả dựa trên các truy vấn con

  1. get danh sách widget (http)
  2. cho mỗi widget

    a) có được một danh sách các bài viết (http) cho các loại phụ tùng cho
    b) lưu lại tất cả những để db
    c) tiến hành đầu tiên mới nhất bài viết() trong danh sách và cập nhật wi dget.articleName và widget.articleUrl với các giá trị thích hợp từ bài viết này

  3. biến đổi trở lại vào danh sách và đầy đủ

Tuy nhiên tôi không chắc chắn phải làm gì sau khi bước 2a. Dưới đây là mã của tôi cho đến nay

apiService.getWidgets(token) 
    .flatMapIterable(widgets -> widgets) 
    .flatMap(widget -> apiService.getArticles(token, widget.type)) 
    ... 
    .toList() 
    .subscribe(
    modifiedWidgets -> saveWidgets(modifiedWidgets), 
    throwable -> processWidgetError(throwable) 
); 

Tôi đã chơi xung quanh với một số nhà khai thác nhưng khi chaining, tôi luôn luôn dường như thu hẹp quá xa (ví dụ như có được một xử lý trên một bài báo duy nhất) và sau đó không còn có thể truy cập tiện ích ban đầu để thực hiện sửa đổi.

@GET("/widgets") 
Observable<List<Widget>> getWidgets(@Header("Authorization") String token); 

@GET("/articles") 
Observable<List<Article>> getArticles(@Header("Authorization") String token, @Query("type") String type); 

Trả lời

19

Bạn có thể chèn doOnNext tại một số điểm của con suối để thêm tác dụng phụ:

apiService.getWidgets(token) 
.flatMapIterable(v -> v) 
.flatMap(w -> 
    apiService.getArticles(token, w.type) 
    .flatMapIterable(a -> a) 
    .doOnNext(a -> db.insert(a)) 
    .doOnNext(a -> { 
     w.articleName = a.name; 
     w.articleUrl = a.url; 
    }) 
    .takeLast(1) 
    .map(a -> w) 
) 
.toList() 
.subscribe(
    modifiedWidgets -> saveWidgets(modifiedWidgets), 
    throwable -> processWidgetError(throwable) 
); 

Here is dụ Runnable về điều này.

+0

Brilliant! Cảm ơn bạn đã dành thời gian để cung cấp một câu trả lời toàn diện như vậy. Kiến thức của tôi về RxJava vừa tăng thêm một bậc khác :) – Damian

+0

Câu trả lời rất hay! –

+0

Câu trả lời hay ... –

1

thêm ở đây kể từ khi tôi không thể tìm thấy một ví dụ về lặp lại một danh sách được trả về trong một đối tượng như biến.

getUserAccount(token) 
    .subscribeOn(Schedulers.newThread()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .flatMap(userResponse -> Observable.just(userResponse.list))  //get list from response 
    .flatMapIterable(baseDatas -> baseDatas)       //make the list iterable 
    .flatMap(baseData ->            //on each project, get the details 
      getProjectDetails(baseData.name,token) 
        .subscribeOn(Schedulers.io())      //get network call off the main thread 
        .observeOn(AndroidSchedulers.mainThread())) 
    .subscribe(
      (dataResponse) -> { 
       Timber.d("Got Data Details:" + dataResponse); 
      }, 
      (error) -> { 
       Timber.e("Got Error:" + error.getMessage()); 
      }, 
      () -> { 
       Timber.d("Completed Data Details"); 
      } 
    ); 
0

Câu trả lời của akarnokd khá hữu ích nhưng có thể gây ra NetworkOnMainThreadException. Để giải quyết mà tôi đã thêm

.observeOn(AndroidSchedulers.mainThread()) 
.subscribeOn(Schedulers.io()) 

trên tất cả các yêu cầu

apiService.getWidgets(token) 
.observeOn(AndroidSchedulers.mainThread())  //added this 
.subscribeOn(Schedulers.io())     //added this 
.flatMapIterable(v -> v) 
.flatMap(w -> 
    apiService.getArticles(token, w.type) 
    .observeOn(AndroidSchedulers.mainThread()) //added this 
    .subscribeOn(Schedulers.io())    //added this 
    .flatMapIterable(a -> a) 
    .doOnNext(a -> db.insert(a)) 
    .doOnNext(a -> { 
     w.articleName = a.name; 
     w.articleUrl = a.url; 
    }) 
    .takeLast(1) 
    .map(a -> w) 
) 
.toList() 
.subscribe(
    modifiedWidgets -> saveWidgets(modifiedWidgets), 
    throwable -> processWidgetError(throwable) 
); 
Các vấn đề liên quan