2016-06-02 10 views
1

Wenn ich folgendes für das Verständnis haben, werden Futures in Reihenfolge ausgeführt werden: f1, f2, f3:Zum Verständnis - ausführen Futures um

val f = for { 
     r1 <- f1 
     r2 <- f2(r1) 
     r3 <- f3(r2) 
    } yield r3 

Für diese jedoch alle Futures am gestartet gleichzeitig:

val f = for { 
     r1 <- f1 
     r2 <- f2 
     r3 <- f3 
    } yield ... 

Wie kann ich die Reihenfolge erzwingen (ich will diese Reihenfolge der Ausführung f1, f2, f3)

?
+0

Was sind 'f1',' f2', 'f3' im ersten Fall und im zweiten Fall? – Dima

+0

Zum Beispiel 'f1' ist' val f1: Zukunft [Einheit] = Zukunft { Thread sleep 5 println (1) } 'aber es denkt, es ist egal, ich bin nur neugierig auf einen Weg Durchsetzung der Ordnung zwischen den Futures, auch wenn sie nicht von denselben Daten abhängig sind. – octavian

Antwort

3

Es ist egal was f1, f2, f3 sind: Eine Zukunft beginnt mit der Ausführung sobald sie erstellt wird. In Ihrem ersten Fall muss f2(r1) eine Funktion sein, die eine Zukunft zurückgibt, so dass die Zukunft beginnt, wenn die Funktion aufgerufen wird, was geschieht, wenn r1 verfügbar wird.

Wenn der zweite Fall der gleiche ist (f2 ist eine Funktion), dann Verhalten wird das gleiche wie im ersten Fall sein, Ihre Futures werden der Reihe nach nacheinander ausgeführt werden.

Aber wenn man die Futures außerhalb des for erstellen und diese nur auf Variablen zuweisen f1, f2, f3, dann durch die Zeit, die Sie im Inneren des Verstehens zu bekommen, sie sind bereits läuft.

2

Future sind eifrige Konstrukte, das heißt, sobald sie erstellt sind, können Sie nicht diktieren, wann sie verarbeitet werden. Wenn das Future bereits vorhanden ist, wenn Sie versuchen, es zu einem Verständnis zu verwenden, haben Sie bereits die Möglichkeit verloren, seine Ausführungsreihenfolge zu sequenzieren.

Wenn Sie Bestellung auf ein Verfahren erzwingen, die Future Argumente akzeptiert dann müssen Sie die Auswertung in einem Thunk wickeln:

def foo(ft: => Future[Thing], f2: => Future[Thing]): Future[Other] = for{ 
    r1 <- ft 
    r2 <- f2 
} yield something(r1, r2) 

Wenn auf der anderen Seite, können Sie die Future definieren möchten innerhalb einer Methode Körper, dann statt val ein def

def foo() ={ 
    def f1 = Future{ code here... } 
    def f2 = Future{ code here... } 
    for{ 
    r1 <- f1 
    r2 <- f2 
    } yield something(r1, r2) 
2

Ausführen Futures verwenden für das Verständnis ist das Standardverhalten. Es ist gut, wenn wenige Aufgaben parallel ohne Blockierung bearbeitet werden.

Aber wenn Sie procecessing Ordnung bewahren wollen, müssen Sie Möglichkeiten:

  • Senden Ergebnis der ersten Aufgabe Sekunde wie in Ihrem Beispiel
  • Verwendung andThen Betreiber

    val allposts = mutable.Set[String]()  
    Future { 
        session.getRecentPosts 
    } andThen { 
        posts => allposts ++= posts 
    } andThen { 
        posts => 
        clearAll() 
        for (post <- allposts) render(post) 
    }