在没有事件总线的情况下触发事件时自动从可观察对象中获取项目

Automatically get items from observable when an event is fired without an eventbus

当您有一个外部事件告诉您应该从 observable 中自动检索新项目时,最好的方法是什么?

例如,假设我有 ItemRepository 实现了 getAllItems() 方法(来自 Web 服务的 returns Observable<List<Item>>),然后是外部事件(如推送通知)告诉我的应用程序需要刷新数据。 (ItemRepository 也用在 Presenter 中,演示者调用了 getAllItems 并在 onNext 上刷新了数据。)

我知道这可以通过事件总线轻松完成(侦听该事件,当它被触发时,再次获取),但我只是想知道是否可以完全自动完成。

谢谢。

编辑

这是我在 SQLBrite 库的帮助下提出的解决方案,但不确定它是否是最好或最干净的方法。 我们有一个 PublishSubject,事件被发送到:

PublishSubject<Object> updateEvent;

在 getAllItems() 方法中,我们检查来自该主题的事件:

public Observable<List<Item>> getAll() {
    Observable.OnSubscribe<List<Item>> subscribe = subscriber -> {
        updateEvent.subscribe(s -> {
            subscriber.onNext(dbItemRepository.getAll());
        });
        subscriber.onNext(dbItemRepository.getAll());// for the first call
    };
    final Observable<List<Item>> automatonObservable = Observable.create(subscribe) =
            .onBackpressureLatest()
            .observeOn(Schedulers.computation())
            .onBackpressureLatest();
    return automatonObservable;
}

您应该使用主题。

看看吧。

public class ExampleUnitTest {
    @Test
    public void testSample() throws Exception {
        ItemRepository itemRepository = new ItemRepository();

        itemRepository.getAllItems()
                .doOnNext(items -> System.out.println("Initializing emission..."))
                .flatMap(Observable::from)
                .subscribe(System.out::println);

        List<Item> items = new ArrayList<>();

        items.add(new Item("First"));
        items.add(new Item("Second"));

        itemRepository.publishNewItems(items);

        items.add(new Item("Third"));
        items.add(new Item("Fourth"));

        itemRepository.publishNewItems(items);
    }

    public class ItemRepository {
        private PublishSubject<List<Item>> itemsListSubject = PublishSubject.create();

        public Observable<List<Item>> getAllItems() {
            return itemsListSubject;
        }

        public void publishNewItems(List<Item> items) {
            itemsListSubject.onNext(items);
        }
    }

    public class Item {
        private String name;

        public Item(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Item{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
}

上面的代码将打印:

Initializing emission...
Item{name='First'}
Item{name='Second'}
Initializing emission...
Item{name='First'}
Item{name='Second'}
Item{name='Third'}
Item{name='Fourth'}

因此,您有一个可以随时发出项目列表的可观察对象。

我建议您查看主题文档 here

希望对您有所帮助。

此致。

我认为Rodrigo Henriques的想法是正确的,但我们需要根据你的问题稍微修改一下:

public static Observable<String> observeRepositoryUpdates(ItemsRepository repo, Observable<Void> updateTrigger) {
  updateTrigger
    //you can insert observeOn here
    .flatMap(event -> repository.getAllItems());
}

public static void doWork() {
  ItemsRepository repo = new ItemsRepository();
  PublishSubject<Void> updateTrigger = PublishSubject.create();

  observeRepositoryUpdates(repo, updateTrigger)
    .subscribe(items -> System.out.println(items.toString());

  updateTrigger.onNext(null);//trigger update
}

根据您的事件,它不一定是 PublishSubject,任何其他可观察对象都可以触发存储库更新。

如果您的事件经常发生并且您想放弃已经 运行 存储库更新并开始新的,您可以使用运算符 switchMap.