在没有事件总线的情况下触发事件时自动从可观察对象中获取项目
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.
当您有一个外部事件告诉您应该从 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.