2016-12-22 1 views
3

번호 :미래의 가치는 변수에 바인딩되었는지 여부에 달려 있습니다.

import scala.concurrent.Future 
import scala.util.{Failure, Success} 
import scala.concurrent.ExecutionContext.Implicits.global 

/** 
    * Created by IDEA on 12/23/16. 
    */ 
object Demo extends App { 
    val fut = Future { 
    Thread.sleep(100) 
    21 + 21 
    } 
    val f = Future { 5 } 
    Thread.sleep(200) 
    val fut1 = fut.map(_ + 1) 
    println(fut1) // Future(Success(43)) 
    println(fut1.value) // Some(Success(43)) 
    println(fut.map(_ + 1).value) // None 
    fut.map(_ + 1).onComplete { 
    case Success(v) => println(v) 
    case Failure(e) => println(e) 
    } // 43 

    (for { 
    x <- Future {Thread.sleep(100); 21 + 21} 
    y <- Future {Thread.sleep(100); 21 + 22} 
    } yield x + y).andThen { 
    case Success(v) => println(v) 
    } 
    Thread.sleep(5000) 
} 

참고 차이 : 직접적 None 제공 입수하면서

println(fut1.value) // Some(Success(43)) 
println(fut.map(_ + 1).value) // None 

즉 변수에 할당 한 후에 미래의 값을 가져 오는 내게 Some(Success(43))을 준다. 왜?

또한 println(fut.map(_ + 1).value) 줄 뒤에 호출되었지만 onComplete 메서드는 예상되는 동작을 생성합니다. 스칼라 2.12.0

답변

7

fut.map(_ + 1)

누구 .value 아직 완료되지 않았을 수 있습니다 새로운 Future 반환합니다. 그렇지 않다면 Noneprintln 쇼를 얻습니다. 그렇지 않으면 Some(Success(43))이 표시됩니다.

당신은 REPL에서 볼 수 있습니다

// Paste the body of your Demo object before 
// Then repeatedly call the last println: 

scala> println(fut.map(_ + 1).value) // None 
Some(Success(43)) 

scala> println(fut.map(_ + 1).value) // None 
None 

scala> println(fut.map(_ + 1).value) // None 
Some(Success(43)) 

scala> println(fut.map(_ + 1).value) // None 
Some(Success(43)) 

scala> println(fut.map(_ + 1).value) // None 
None 

편집 :
(그것에 변경없이) 코드의 비 결정적 결과 표시 :

scala> Demo.main(Array()) 
List() 
None 
Some(Success(43)) 

scala> Demo.main(Array()) 
List() 
None 
None 

scala> Demo.main(Array()) 
List() 
None 
None 

scala> Demo.main(Array()) 
Success(43) 
Some(Success(43)) 
Some(Success(43)) 
+0

메인 쓰레드를 잠자 게하면 내 컴퓨터에서 전혀 도움이되지 않는 것 같습니다. 스칼라 앱에서 이것을 확인할 수 있습니까? – qed

+0

@qed : 무슨 뜻인지 모르겠습니다. '.map' 결과를 할당하지 않은'Thread.sleep'는 아무런 영향을 미치지 않으며, 그것을 할당하는 것은 질문과 모순됩니다. – Marth

+0

제 편집을 참조하십시오. – qed

2

I을 선물 거래가 끝날 때까지 기다리지 못하기 때문에 타이밍 문제가 발생했다고 생각합니다. 스칼라 REPL에서 마지막 계산을 실행할 때 실제로는 None, 때로는 Some(Success(43))을 인쇄합니다.

그러나 예를 들어 실행 :

fut.map(_ + 1).onComplete { 
    case Success(v) => println(v) 
    case Failure(ex) => 
} 
Thread.sleep(100) 

항상 43을 인쇄합니다. 결과를 보려면 장래에 완료되기 전에 프로그램이 종료되지 않도록해야합니다.

+0

내 컴퓨터에서 5 초 동안 스레드를 잠자도 도움이되지 않습니다. – qed

+0

도중에 'oncomplete'해야합니다. 'onSuccess'는 더 이상 사용되지 않습니다. – qed

+0

5 초 동안 'Thread.sleep'이 어디에 있 었는가? 내가 붙여 넣은 코드, 즉 프로그램이 끝난 후에 시도 했습니까? 그래, 네 말이 맞아 보인다. 'onSuccess'는 Scala 2.12에서 더 이상 사용되지 않습니다. – m01

관련 문제