2016-07-14 3 views
3

Ich bin neu in Scala. Ich habe eine Funktion namens calculateSubTotal mit einer Liste von Produkt-ID und Mengen geschrieben.Warum konnte eine Blockvariable in der Scala-Funktion nach der Ausführung des inneren Blocks (der inneren Blöcke) nicht aktualisiert werden?

Zuerst wird die Funktion ein Produkt aus der Datenbank für jede Produkt-ID abholen, dann individual sub total berechnen und mit sub total summieren. Ich möchte die berechnete Teilsumme zurückgeben. Die Berechnung ist in Ordnung, aber leider gibt es die initialized value anstatt die calculated value zurück. Was ist mit meinem Code? Der Code ist als: -

def calculateSubTotal(productIds: Seq[Int], quantities: Seq[Int]) = { 
    var subTotal = 0.0 
    for (index <- 0 to productIds.length - 1) { 
    val productId = productIds(index) 
    val quantity = quantities(index) 
    val futureProduct = Products.read(productId) 
    for { 
     product <- futureProduct 
    } yield { 
     val listPrice = product.get.listPrice 
     subTotal += listPrice * quantity 
    } 
    } 
    subTotal 
} 

die obige Funktion Schauen Sie immer wieder 0.0, wie ich initialisiert. Was wird der richtige Code sein?

+1

Was ist der resultierende Typ der 'Products.read()' Methode? Ist es "Zukunft [Option [Produkt]]"? –

+0

Ja ... 'Products.read()' returns 'Zukunft [Option [Produkt]]' @ PawełJurczenko – Johir

Antwort

1

Das Problem ist, dass der resultierende Typ Ihrer Products.read() Methode Future[Option[Product]] ist, was bedeutet, dass in Ihrem aktuellen Code es auf einem anderen Thread ausgeführt wird. Der Hauptthread (der ausführende calculateSubTotal) wartet nicht auf eine erfolgreiche Ausführung von Products.read() und gibt sofort das Ergebnis() zurück. Dies ermöglicht nichtdeterministische Ergebnisse: manchmal wird überhaupt nicht geändert, manchmal wird es teilweise modifiziert und manchmal erhalten Sie ein ordentliches Ergebnis. Die einfachste Lösung wäre es, synchron zum Products.read() Ergebnis warten:

import scala.concurrent.duration.Duration 
import scala.concurrent.Await 

Await.result(Products.read(productId), Duration.Inf) 

Die asynchrone Lösung würde erfordern calculateSubTotal in einer Weise Umschreiben, die Future[Int] zurückgibt.

+0

Was wäre die asynchrone Lösung? ..... @ Paweł Jurczenko – Johir

Verwandte Themen