2013-10-10 63 views
1

我必须同时执行大约10到15个查询。在哪里,这些查询是相互依赖的,我将这些查询放在一起。否则,每个查询都有一个未来。现在我只需要在执行所有查询时执行一个响应,指示包含未来的函数的成功或失败。当所有期货在scala中完成时执行任务

val f1 = future{SQL("insert into user_general_info (user_id, userFName, userLName, displayAs)" + 
    "values(" + userId + ",'" + form.fname + "','" + form.lname + "','1')").executeInsert(); 
} 

val f2 = future { 
    SQL("insert into personal('" + userId + "',1,1,0,0,1,'ALL',0,'E')").executeInsert(); 
} 

/* 
and so on...upto about f1 to f14 futures... 
*/ 

现在我所做的是:

val job = for { 
    a1 <- f1 
    a2 <- f2 
    a3 <- f3 
    a4 <- f4 
    a5 <- f5 
    a6 <- f6 
    a7 <- f7 
    a8 <- f8 
    a9 <- f9 
    a10 <- f10 
    a11 <- f11 
    a12 <- f12 
    a13 <- f13 
    a14 <- f14 
} yield() 

var res: Boolean = false 

job.onSuccess { 
    case result => res = true 
} 

if(res) 
    List((1, userId, username)) //1 means success 
else 
    List((-2, userId, username)) //-2 means failure 

的问题是,所有查询都没有运行,响应List((-2,userId,username))基于可变资源发送。但是当所有的期货都完成时,List((1,userId,username))应该已经被退回。帮助...

+0

与您展示的是,该方法的另一个问题查询不会同时执行,而是按顺序执行。对期货的理解提供了将期货链接成序列的手段,以便序列中后面的那些只有在成功之前才执行。 tehlexx的答案是正确的,这就是你在这种情况下寻找的东西(即使用Future.sequence而不是a理解)。 –

+0

@MarkS你确定。如果他在理解之前定义了期货,那么所有期货都会立即以并行方式执行。理解仅等待结果。所以如果第一个将来需要的时间比第一个flatMap被执行的时间要多,如果这个结果完成的话。然后所有其他flatMap链都立即执行,因为所有其他期货已经完成。我可能是错的。 – akkie

+0

@akkie如果未来已经创建,那么你是对的。我被卡在想象中,未来是在理解中创造的。当然,如果它们是在之前创建的,那么它们将被执行而不管(并行)。 –

回答

6

您可以使用Futures.sequence来转换未来单一期货的列表。从Composing Futures

代码示例:

// oddActor returns odd numbers sequentially from 1 as a List[Future[Int]] 
val listOfFutures = List.fill(100)(akka.pattern.ask(oddActor, GetNext).mapTo[Int]) 

// now we have a Future[List[Int]] 
val futureList = Future.sequence(listOfFutures) 

// Find the sum of the odd numbers 
val oddSum = futureList.map(_.sum) 
oddSum foreach println 

在一个侧面说明,我会建议返回一个Option表明成功或失败,例如

if(res) Some(List(userId, userName)) 
else None 
相关问题