I am new to scala. I have written a function named calculateSubTotal with a list of product id and quantities.
At first the function will pick up a product from the database for each of the product id, then calculate the individual sub total and sum up with sub total. I would like return the calculated sub total. Calculation is OK but unfortunately it returns the initialized value rather than the calculated value. Whats with my code. The code is as:-
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
}
Look the above function always returns 0.0 as I have initialized. What will be the correct code?
The problem is that the resulting type of your
Products.read()method isFuture[Option[Product]], which means that in your current code it's executed on a different thread. The main thread (the one executingcalculateSubTotal) doesn't wait for a successful execution ofProducts.read()and it returns the result (subTotalin this case) right away. This will allow nondeterministic results: sometimessubTotalwon't be modified at all, sometimes it'll be modified partially and sometimes you'll get a proper result. The simplest solution would be to synchronously wait forProducts.read()result:The asynchronous solution would require rewriting
calculateSubTotalin a way, that returnsFuture[Int].