Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
RxJava-可观察到的单个热源?好主意还是坏主意?_Java_Reactive Programming_Rx Java - Fatal编程技术网

RxJava-可观察到的单个热源?好主意还是坏主意?

RxJava-可观察到的单个热源?好主意还是坏主意?,java,reactive-programming,rx-java,Java,Reactive Programming,Rx Java,我很欣赏RxJava能够处理的所有复杂性,从处理用户事件到大型复杂的反应式算法结构。然而,我仍然在为源可观察的的开始、所有事件的起源以及如何管理多个事件起源而挣扎 我知道这个问题的答案可能是“视情况而定”,但将源事件合并到单个主题或某种形式的热可观察事件是一个坏主意吗 例如,假设我有一个数据驱动的桌面应用程序。我有一个可枚举项,用于标识根级别的事件类型 public enum AppEvent { TRANSACTIONS_REFRESH, CATEGORIES_REFRE

我很欣赏RxJava能够处理的所有复杂性,从处理用户事件到大型复杂的反应式算法结构。然而,我仍然在为源
可观察的
的开始、所有事件的起源以及如何管理多个事件起源而挣扎

我知道这个问题的答案可能是“视情况而定”,但将源事件合并到单个
主题
或某种形式的热可观察事件是一个坏主意吗

例如,假设我有一个数据驱动的桌面应用程序。我有一个可枚举项,用于标识根级别的事件类型

public enum AppEvent { 
     TRANSACTIONS_REFRESH,
     CATEGORIES_REFRESH
}

然后我有了一个
AppEventEngine
singleton,它包含了一个
PublishSubject
,并提供了一种发布事件和访问
Observable)的方法,一种编写RxJava桌面应用程序的洁净方式?或者我应该避免使用
PublishSubject
并以不同的方式(以分散的方式)派生事件吗?

我认为这是一种有效的模式,也是
PublishSubject
的常见用例。不过,有一点建议是,如果您希望事件从不同的线程推送到它,那么就序列化来自
PublishSubject
的排放(除非推送事件之间存在正式的before关系,但这可能是您不需要的优化)。因此,宣言应该是:

private final Subject<AppEvent> eventBus =
    PublishSubject.create().toSerialized();
私有最终主题事件总线=
PublishSubject.create().toSerialized();

我很好奇,序列化后它会在单个线程上发出吗?或者它只是同步“onNext”()'一次只调用并让一个线程进入?它可能会在多个线程上发出,但在线程a上发出时会保留一个队列。如果线程B将事件推送到主题,那么它将被添加到队列中,以便在线程a上发出。如果当线程B推送到主题时队列中没有任何内容,则会在线程B上发出。此位欺骗提供了正确的排放序列,而不需要任何锁。更多非阻塞RxJava的优点!有趣的是,我在猜测线程重用是如何工作的。所以我猜在这种特殊情况下,当线程B将排放责任传递给线程A时,那么线程B永远不必阻塞。
public final class CategoryManager {

    private final Database db = //instantiate database;
    private final Observable<List<Category>> categories;

    private CategoryManager() { 
        categories = AppEventEngine.get().getEvents(AppEvent.CATEGORIES_REFRESH)
                .flatMap(e -> db.select("SELECT * FROM CATEGORY").get(rs -> new Category(rs.getInt("ID"), rs.getString("DESC"))).toList()).cache(1);
    }

    public Observable<List<Category>> getCategories() { 
        return categories;
    }
}
public final class SomeClientUX { 
    //gui code 

    public void categoryRefreshButtonPressed() {
        AppEventEngine.get().post(AppEvent.CATEGORIES_REFRESH);
    }
}
private final Subject<AppEvent> eventBus =
    PublishSubject.create().toSerialized();