2014-12-02 83 views
0

快速的问题,如果在斯卡拉你成功承诺这样的承诺,斯卡拉诺言澄清

val successful = Promise[List[T]]()  //Create a promise which will be returning the results 
successful.success(Nil) 

这会不会完成承诺,因此不会允许您进一步写入承诺?哪些还会触发onComplete回调的承诺?

我问的原因是我想了解下面的一段代码,我试图理解为什么在未来的计算开始之前,这个承诺被初始化为零。

def all[T](fs: List[Future[T]]): Future[List[T]] = { 
    val successful = Promise[List[T]]()  //Create a promise which will be returning the results 
    successful.success(Nil)     //Initialize the profile 
    fs.foldRight(successful.future) {  //Create the Aggregate for the fold right which will be an empty future 
    //for each element extract the element from the future and append to our aggregate 
    //f -> Future[T] acc -> Future[List[T]] 
    (f, acc) => for { x <- f; xs <- acc } yield x :: xs 
    } 
} 

思考出来大声我要说完成承诺的原因是,有没有callbacsk连接,因此,当它成功,我们不关心。如果是这样,唯一的原因是使用承诺就是利用它的未来。那么,如果不使用我们实际上不需要的承诺,它们就不是一种更简单/更简洁的方式来定义未来?

+0

在这种情况下,它需要处理'fs'为空的情况。 – Ryan 2014-12-02 19:03:05

+0

所以我们假设fs不为null。由于之前的成功,foldright会触发onComplete回调吗? – MrX 2014-12-02 19:06:55

+0

没有调用'onComplete'来注册回调。 – vptheron 2014-12-02 19:20:15

回答

1

是的,一个承诺只完成一次(我不知道你的意思是“onComplete回调”,我没有看到标准库Promise文档中的这样的事情)。但是,当然承诺的future可用并按预期工作,即使承诺已经完成。这看起来是一种使用Future.successful(Nil)作为foldRight的初始元素的过于复杂的方式。

+0

对不起onComplete我指的是承诺的onSuccess方法,它不是代码中的任何地方,但它只是一个假设的问题。 因此,要确保我明白你正确 successful.success(无) 初始化未来:未来[列表[T]为零,这将在foldRight可基本使用。 有没有办法以更优雅的方式编写下面的代码? – MrX 2014-12-02 19:34:08

+0

您可以将代码编写为'fs.foldRight(Future.successful(List [T]())){...'。如果你使用Scalaz并且在范围内有一个隐含的ExecutionContext,那么整个函数就是'fs.sequence'(至少我认为* scalaz在某处有一个'Applicative [Future]')。 – lmm 2014-12-02 19:45:55