簡體   English   中英

RxJava從並行計算中排序輸出

[英]RxJava sorted output from parallell computation

我有一個我想要在parallell中執行的任務列表,但我想以與原始列表相同的順序顯示任務的結果。 換句話說,如果我有任務列表[A,B,C],我不希望在顯示A結果之前顯示B結果,但我也不想等到A-task完成后再啟動B -任務。

另外,我希望盡快顯示每個結果,換句話說,如果任務按順序B完成,那么A,然后C,我不想在收到B-result時顯示任何內容,然后顯示A-當我收到A結果時,結果會立即跟隨B結果,然后在收到結果時顯示C結果。

當然,通過為每個任務創建一個Observable,將它們與merge相結合,並在計算線程池上進行預訂,然后編寫一個為不按順序接收的任何結果保存緩沖區的訂閱服務器,這當然不是非常棘手。 然而,Rx經驗法則傾向於“已經有了一個運算符”,所以問題是“什么是正確的RxJava解決方法?” 如果確實有這樣的事情。

“那里並沒有那么多的經營者”。 雖然,在1.0.15-SNAPSHOT版本中有一個實驗性的concatEagar()運算符,但聽起來它就像你正在尋找的那樣。 請求concatEager的請求

repositories {
    maven { url 'https://oss.jfrog.org/libs-snapshot' }
}

dependencies {
    compile 'io.reactivex:rxjava:1.0.15-SNAPSHOT'
}

如果你想推出自己的臨時解決方案,直到concatEager()得到批准的點頭。 你可以嘗試這樣的事情:

public Observable<Result> concatEager(final Observable<Result> taskA, final Observable<Result> taskB, final Observable<Result> taskC) {
    return Observable
            .create(subscriber -> {
                final Observable<Result> taskACached = taskA.cache();
                final Observable<Result> taskBCached = taskB.cache();
                final Observable<Result> taskCCached = taskC.cache();

                // Kick off all the tasks simultaneously.
                subscriber.add(
                        Observable
                                .merge(taskACached, taskBCached, taskCCached)
                                .subscribe(
                                        result -> {     // Throw away result
                                        },
                                        throwable -> {  // Ignore errors
                                        }
                                )
                );

                // Put the results in order.
                subscriber.add(
                        Observable
                                .concat(taskACached, taskBCached, taskCCached)
                                .subscribe(subscriber)
                );
            });
}

請注意,上面的代碼完全未經測試。 可能有更好的方法來做到這一點,但這是首先想到的......

看來你需要concatEager來完成這個任務,但是有些可能用1.0.15之前的工具實現它,而不需要“創建”Observables。 這是一個例子:

Observable<Long> source1 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(10);
Observable<Long> source2 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(20);
Observable<Long> source3 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(15);

Observable<Observable<Long>> sources = Observable.just(source1, source2, source3);

sources.map(v -> {
    Observable<Long> c = v.cache();
    c.subscribe(); // to cache all
    return c;
})
.onBackpressureBuffer() // make sure all source started
.concatMap(v -> v)
.toBlocking()
.forEach(System.out::println);

缺點是它保留了整個序列持續時間的所有值。 這可以通過一種特殊的主題來修復: UnicastSubject但是RxJava 1.x沒有一個,可能沒有“正式”。 但是,您可以查看我的一篇博文,並為自己構建並擁有以下代碼:

//...
sources.map(v -> {
    UnicastSubject<Long> subject = UnicastSubject.create();
    v.subscribe(subject);
    return subject;
})
//...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM