2016-10-10 43 views
1

我目前正在編寫擴展Future伴侶對象的代碼。一個功能我想實現是AnyScala Future和Thread.sleep的奇怪行爲

//returns the future that computes the first value computed from the list. If the first one fails, fail. 
def any[T](fs: List[Future[T]]): Future[T] = { 
    val p = Promise[T]() 

    fs foreach { f => { 
    f onComplete { 
     case Success(v) => p trySuccess v 
     case Failure(e) => p tryFailure e 
    } 
    } } 

    p.future 
} 

我試着用

test("A list of Futures return only the first computed value") { 
    val nums = (0 until 10).toList 
    val futures = 
     nums map { n => Future { Thread.sleep(n*1000); n } } 

    val v = Await.result(Future.any(futures), Duration.Inf) 

    assert(v === 0) 
    } 

但返回的值是1,不是0。當我切換休眠時間n*1000(n+1)*1000,它來測試我的代碼工作正常(返回0)。

0上調用睡眠有什麼特別效果嗎?

回答

1

Thread.sleep是阻塞操作在Future但你不能用信號通知你正在做這樣ExecutionContext,這樣的行爲會根據您的ExecutionContext使用什麼和多少個處理器機器有改變。您的代碼工作與ExecutionContext.global預期如果添加blocking

nums map { n => Future { blocking { Thread.sleep(n*1000); n } } } 
+0

哦,我忘了添加'blocking'塊。我錯過了這些線程在執行上下文中運行。您的解決方案完全正常。謝謝。 –

0

我認爲函數名是any所以我覺得你實現any正確的方式。 但是,如果你想要第一個,你只需從列表參數fs獲得第一個元素,並完成一個承諾。

+0

我覺得我在評論中誤用了「第一」這個詞。我想 - 而且需求描述 - 返回在時域中首先計算的值。我非常肯定這個實現符合要求。 –