2017-11-26 3 views
0

Ich benutze rxjs, um einige komplexe Mausgesten zu handhaben.Wie man eine Sequenz von Observablen in rxjs zusammensetzt

Eine dieser Maßnahmen besteht darin, die Maus während eines Ziehvorgangs mehrmals zu "schütteln" (von links nach rechts, von rechts nach links, ...).

Da ich nicht weiß, ob der Benutzer beginnt, indem er die linke oder rechte bewegt, verwende ich 'race()' zu akzeptieren, was zuerst beginnt.

Mein Problem ist, dass wenn der erste "Schütteln" Beobachter abgeschlossen ist, der zweite bereits abgeschlossen ist.

ich ein vereinfachtes Beispiel hier gemacht habe, auf jsbin (http://jsbin.com/wuzodog/3/edit?html,js,output.)

(I negative Zahlen verwenden als "Maus nach links" und positiven als "Maus rechts" in diesem vereinfachten Beispiel.)

der Kern des Problems ist hier gezeigt ...

const subMouseMove = new Rx.Subject<number>(); 

    const obLeft = subMouseMove.filter(m => m < 0); 
    const obRight = subMouseMove.filter(m => m >= 0); 

    const get_obLeftUntilRight =() => obLeft.takeUntil(obRight); 
    const get_obRightUntilLeft =() => obRight.takeUntil(obLeft); 

    const get_obShake =() => Rx.Observable.race(get_obLeftUntilRight(), get_obRightUntilLeft()); 

    const obDragShakeAndDrop = Rx.Observable.concat(
    get_obShake(), 
    get_obShake(), 
); 

    //sending the following values to subMouseMove 
    [-1, -2, 3, 4, -5].forEach((v, i, a) => setTimeout(() => subMouseMove.next(v), i * 10)); 

Das Problem ist, dass beide Instanzen von get_obShake() ist c ompleted zur gleichen Zeit.

Die Ergebnisse Ich bin von der jsbin bekommen sind:

Actual Results

Ich würde meine Ergebnisse erwarten sein:

Expected results

Wenn ich das Beispiel (http://jsbin.com/wuzodog/4/edit?html,js,output) ändern, die "shake left/right" und die "shake right/left" direkt aufrufen und dabei "race()" umgehen, bekomme ich die "erwartete" Ausgabe.

Kann jemand erklären, warum der zweite Shake im ersten Beispiel früh fertig ist?

+0

Ich fühle mich wie diese Ihnen helfen zu verstehen, warum: https://github.com/ReactiveX/rxjs/issues/2641 – bryan60

+0

ich ein kleines Bugfix machen würde nicht im Zusammenhang mit der Frage: 'obRight' wahrscheinlich sollte nur nehmen, wenn' m' ist größer als 0, nicht gleich, weil sonst an Ort und Stelle bleibt auch ein Ereignis –

Antwort

2

Es ist schwierig, aber die Antwort ist rationaler als Sie denken. Das Problem ist, dass Race akzeptiert auch Abschluss als der erste Gewinner Observable.

const get_obLeftUntilRight =() => obLeft.takeUntil(obRight); 
const get_obRightUntilLeft =() => obRight.takeUntil(obLeft); 

Wenn wir an diesen beiden Observablen aussehen, wenn es ‚links‘ Ereignis ist, wird der erste emittieren und die zweite wird abgeschlossen sofort. Wenn wir ein "richtiges" Ereignis bekommen, wird das erste sofort und das zweite ...

Dies ist wahrscheinlich das, was Sie wollen:

const get_obLeftUntilRight =() => obLeft.take(1).concat(obLeft.takeUntil(obRight)); 
const get_obRightUntilLeft =() => obRight.take(1).concat(obRight.takeUntil(obLeft)); 
+0

Most excellence. Neu zu formulieren, 'get_obLeftUntilRight()' war _requiring_ ein 'obLeft' vor der Vervollständigung wegen eines' obRight'. Richtig? – bnieland

+0

Als eine Folgefrage, 'takeUntil (obRight)', _consumes_ das 'obRight', so dass es nie eine Chance erhält, ausgegeben zu werden. Gibt es eine einfache Lösung für dieses Problem? – bnieland

+0

Hier ist die jsBin für die Behebung: http://jsbin.com/dadafil/2/edit?html,js,output – bnieland

-1

Der Unterschied zwischen den beiden ist, dass Ausgänge jsBin

** NEXT: get_obShake2 = 4 

vom ersten fehlt, weil es race beseitigt hat.

Also, es ist nicht so, dass der zweite Shake früh fertig ist, es ist nur eine kürzere Sequenz.

Fügen Sie einige timestamp() hinzu, um es auszuprobieren.

Ich muss sagen, ich habe nicht das Gefühl, dass dieser Code tut, was Sie vorhaben, aber das könnte mein Mangel an Verständnis sein.

Verwandte Themen