2016-11-04 4 views
1

Wir haben ein Fenster mit Suchfeld. Jedes Mal, wenn der Benutzer etwas eingibt, wird eine Suche durchgeführt.RxJava führt nur ein Observable auf einmal aus

  1. Such-Ereignis wird in Datenstrom übersetzt.

  2. Bei jeder neuen Suche müssen wir den asynchronen Netzwerkbetrieb starten und den vorherigen Vorgang schließen. Wie archiviert man diesen Effekt?

Edit1: Hier ist, was ich versucht habe. Es führt alle Observablen aus! Nicht der einzige letzte, wo ist ein Fehler?

PublishSubject<Integer> subject = PublishSubject.create(); 

subject.switchMap(integer -> Observable.fromCallable(() -> { 
    try { 
     Thread.sleep(500); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    return "-" + integer + "-"; 
})).subscribe(s -> System.out.print(s)); 
for (int i = 0; i < 30; i++) subject.onNext(i); 
+0

Ich bin selbst noch ein Anfänger, aber könnten Sie statt dessen stattdessen die Sucheingabe des Benutzers beobachten und diese entprellen und dann mit der entlarvten Benutzereingabe Suchen durchführen? – Andreas

+0

@Andreas Ja, es ist eine Hälfte von dem, was ich brauche. Es muss auch nur eine Ausführung gleichzeitig sein usw. jeder neue Wert löscht vorhergehende – dooplaye

+0

Sie können sowohl 'debounce' als auch' switchMap' machen, um die Suche nach jedem Tastendruck zu vermeiden und alte Suchen abzubrechen. – akarnokd

Antwort

3

Verwenden PublishSubject mit switchMap:

PublishSubject<String> subject = PublishSubject.create(); 
subject 
    .switchMap(
    x -> networkOperationObservable(x) 
      .subscribeOn(Schedulers.io)) 
    .subscribe(subscriber); 

Um das Beste aus diesem networkOperationObservable heraus zu bekommen, würde vernünftig auf einen unsubscribe Anruf reagieren (wie in der Nähe der Socket oder was auch immer). Observable.using ist das Werkzeug der Wahl dafür in der Regel.

+0

Bitte überprüfen Sie meine Bearbeitung. – dooplaye

0

PublishSubject ist genau das, was Sie brauchen. Es ist ein Observable Sie können jederzeit Ereignisse hinzufügen.

es erstellen:

private Subject<String, String> filteringSubject = PublishSubject.create(); 

Dann Observable.throttleWithTimeout() Operator:

Subscriber<String> filteringSubscriber = new DefaultSubscriber<>(); 
filteringSubject 
    .throttleWithTimeout(250, TimeUnit.MILLISECONDS) 
    .doOnNext(new Action1<String>() { 
     @Override 
     public void call(String text) { 
      //make a network call 
     } 
    }) 
    .subscribe(filteringSubscriber); 

Verbrauch:

filteringSubject.onNext(text); 
+0

Es ist nicht. Netzwerkanruf muss einen Wert zurückgeben. – dooplaye

+0

Ok, dann 'flatMap'' String' zum Netzwerkanruf und subscribe die ganze 'Obsevable' mit echtem' Subscriber', nicht die falsche. –

Verwandte Themen