2

次のシナリオがあり、RxJava で変換する必要があります。

  1. ローカル データベースから 30 個のアイテムを取得する
  2. これらの 30 エントリで API を呼び出します (1 つの要求)
  3. ローカルデータベースからアイテムを削除します(これにはアイテムリストへのアクセスが必要です)
  4. ループ (?) db が空になるまでこれを 1 ~ 3 回繰り返したい

私がこれまでに行ったことは次のようになります。

fetchAllFromDbObservable()
    .flatMap( (string) -> {
        return Model
    })
    .buffer(30)
    .publish( (List<Model>, Response) -> {
        return callApiObservable(List<Model>);  
    })
    .publish( (Response) -> {
        // how do I get access here to List<Model> ?
        ArrayList<Long> ids = getIdsFromList(List<Model>)
        return removeFromDbObservable(ids);  
    })

質問:

  1. publish を呼び出すのは正しいことですか、それとも when/and/then を使用する必要がありますか?
  2. モデルリストをあるオブザーバブルから別のオブザーバブルに渡すにはどうすればよいですか?

ありがとう

4

1 に答える 1

0

要件の可能な実装は次のとおりです。

import rx.subjects.PublishSubject;
import java.util.List;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.toList;

public class Looper {

    // initialize db with 100 items
    private final List<Integer> db = IntStream.rangeClosed(1, 100)
            .boxed().collect(toList());

    private List<Integer> read30ItemsFromDb() {
        return db.stream().limit(30).collect(toList());
    }

    private void makeApiCall(List<Integer> items) {
        System.out.println(items);
    }

    private void removeFromDb(List<Integer> itemsToBeRemoved) {
        db.removeAll(itemsToBeRemoved);
    }

    private enum Command { NEXT }

    public static void main(String[] args) {
        Looper looper = new Looper();

        PublishSubject<Command> itemsProducer = PublishSubject.create();
        PublishSubject<List<Integer>> itemsConsumer = PublishSubject.create();

        itemsProducer.subscribe(command -> {
            switch (command) {
                case NEXT:
                    List<Integer> items = looper.read30ItemsFromDb();
                    if (!items.isEmpty()) itemsConsumer.onNext(items);
                    else itemsConsumer.onCompleted();
                default:
                    itemsConsumer.onCompleted();
            }
        });

        itemsConsumer
                .doOnCompleted(itemsProducer::onCompleted)
                .subscribe(items -> {
                    looper.makeApiCall(items);
                    looper.removeFromDb(items);
                    itemsProducer.onNext(Command.NEXT);
                });

        // start the loop
        itemsProducer.onNext(Command.NEXT);
    }
}
于 2016-01-14T01:58:21.823 に答える