2016-07-09 15 views
0

固定されて所望の出力が得られます!反復された要素とサブスクライブの間の遅延

私は反復する必要があるアイテムのリストを持っており、各エレメント間には2秒待っています。すべてのアイテムが処理され、サブスクリプションが呼び出されると、もう2秒待っています。ここで

が私のコードです:

rx.Observable.from(new String[] {"Test1", "Test2", "Test3", "Test4"}) 
     .zipWith(rx.Observable.interval(2000, 1000,TimeUnit.MILLISECONDS), (a,b) -> a) 
     .subscribe(name -> { 
      System.out.println(name); 
     }, e -> { 
      System.out.println("ERROR" + e); 
     },() -> { 
      rx.Observable.timer(4000, TimeUnit.MILLISECONDS) 
         .subscribe(notUsed -> "THE END!"); 
     }); 


     try { 
      // Sleep so the program doesn't exit immediately 
      Thread.sleep(10000); 
     } 
     catch (Exception e) { 

     } 

それはかなりいい実行されますが、それが印刷さ購読で「間隔」実行時に「ENDを!」 3回!

TEST1 
TEST2 
TEST3 
TEST4 
THE END! 
THE END! 
THE END! 

これを改善する方法はありますか?

ありがとうございました!あなたの最初のストリーム(Test1-4)が完了したら

答えて

1

、あなたが遅延Observable.timer(2, TimeUnit.SECONDS).map(notUsed -> "The end")

コピーpastableコード

rx.Observable.from(new String[]{"Test1", "Test2", "Test3", "Test4"}) 
       .zipWith(rx.Observable.interval(2000, 1000, TimeUnit.MILLISECONDS), (a, b) -> a) 
       .concatWith(Observable.timer(2, TimeUnit.SECONDS).map(notUsed -> "The end")) 
       .subscribe(name -> { 
          System.out.println(name); 
         }, e -> { 
          System.out.println("ERROR" + e); 
         } 
       ); 


     try { 
      // Sleep so the program doesn't exit immediately 
      Thread.sleep(10000); 
     } catch (Exception e) { 

     } 
+0

素晴らしいです!ありがとうございます@ – Shvalb

+0

.map(..)がvoid(Stringではなく)を返すメソッドを呼び出すように、配列内のすべての項目が出力された後にのみ呼び出されるように、上記のコードを変更するにはどうすればよいですか? – Shvalb

+0

サブスクリプションの完全な部分に 'interval'コールを置くことは可能ですか? – Shvalb

2

後に単一の値を発光ObservableでそれをCONCATことができますまあ、それはあなたが言うまさにませんそれ

time event 
------------------------------------- 
    0 start, wait 2000 ms initially 
2000 emit "Test1", wait 1000 ms 
3000 emit "Test2", wait 1000 ms 
4000 emit "Test3", wait 1000 ms 
5000 emit "Test4", emit the OnCompleted event, wait 2000 ms 
7000 print "THE END!", wait 1000 ms 
8000 print "THE END!", wait 1000 ms 
9000 print "THE END!", wait 1000 ms 
10000 main thread dies 

:-)行うには、私は正確に何をしたいかわからないが、私はあなただけのシングル「ENDを!」したいと推定します。あなたはこれが同様に1000のミリ秒遅れで表示されるようにしたい場合は、次の操作を実行する必要があります。

Observable.from(new String[] {"Test1", "Test2", "Test3", "Test4"}) 
    .zipWith(Observable.interval(2000, 1000,TimeUnit.MILLISECONDS), (a,b) -> a) 
    .concatWith(Observable.timer(1000, TimeUnit.MILLISECONDS).ignoreElements()) 
    .subscribe(
     System.out::println, 
     e -> System.out.println("ERROR" + e), 
     () -> System.out.println("THE END!)); 

あなたが最後に遅延したくない場合は、単に上記concatを削除します。

は何このconcatが行うことは、それが完了して放出される最初のシーケンスからOnCompleted一度Observerに加入する第一の配列(fromzip)を待ちます。 2番目のシーケンスがサブスクライブされると、1000ミリ秒間待機し、要素を放出して完了します(intervalではなくtimerです)。要素(a.k.a. OnNext)を無視するため、OnCompletedイベントが残っているだけで、subscribeのコールバックがトリガーされます。

+0

私はあなたのソリューションを実行しようとします - それは配列要素を無視するようです - しかし、私はそれらをサブスクライブ部分で処理する必要があります。 – Shvalb

+0

いいえ、Observable.timer(...)AFAIKの要素だけを無視します。しかしそれをテストしていない:-) 'ignoreElements'は' concat'の中にあることに注意してください! – RvanHeest

+0

遅延メソッドは新しいスレッドを作成します。 – Shvalb

関連する問題