복붙노트

[SCALA] 명확한 설명은 스칼라에서 선물과 약속에 대한 필요

SCALA

명확한 설명은 스칼라에서 선물과 약속에 대한 필요

나는 스칼라의 약속과 미래 구조의 주위에 내 머리를 얻으려고 노력하고있다.

나는 스칼라 문서에 선물과 약속을 읽고 내가 약속과 선물의 개념이 혼합되어 있다는 느낌을 가지고로 조금 혼란 스러워요했습니다.

스칼라에서 우리는 미래에 첨부 된 콜백을 사용하여 결과를 얻을 수 있습니다.

어디를 잃었어요 약속은 미래가 어떻게?

나는 그 약속과 미래가 어떤 일반적인 일반적인 개념이 가정, 너무 Clojure의 이러한 개념에 대해 읽었지만, 내가 잘못했다처럼 보인다.

val p = promise[T]
val f = p.future

해결법

  1. ==============================

    1.당신은 파이프의 두 가지 측면으로 선물과 약속을 생각할 수 있습니다. 약속 측면에서 데이터를 밀어하고, 미래 측에서 데이터를 꺼내 될 수있다.

    당신은 파이프의 두 가지 측면으로 선물과 약속을 생각할 수 있습니다. 약속 측면에서 데이터를 밀어하고, 미래 측에서 데이터를 꺼내 될 수있다.

    사실, 미래는 비동기 적으로, 어떤 시점에서 제공 될 수있는 값에 대한 자리 표시 자 개체입니다. 이것은 비동기 계산 자체가 아니다.

    비동기 계산을 반환 같은 개체 틀과 스폰이 완료이 자리 객체가 비동기 계산이 미래라는 것을 의미하지 않는다는 것을 미래라는 미래의 생성자가 있다는 사실. 다른 미래의 생성자 / 팩토리 메소드도 있습니다.

    2 별도의 인터페이스로 약속과 미래를 분할하려면 디자인 결정했다. 동일한 인터페이스 미래에서이 두 가지가있을 수 있지만, 그 미래의 고객이 미래의 의도 completer 대신을 완료 할 수있다. 경쟁 completers의 숫자가있을 수 있기 때문에 이것은 예기치 않은 오류가 발생할 것입니다.

    예를 들면 미래의 구조에 의해 산란 비동기 계산을 위해, 더 이상 그 약속을 완료하거나 클라이언트가 그것을 할 것입니다 경우하는지 여부를 명확하게하지 않을 것이다.

    선물과 약속은 프로그램에서 데이터의 흐름을 제한하기위한 것입니다. 아이디어는 데이터가 도착하면 데이터에 대한 구독이 행동하는 것이 미래의 클라이언트를하는 것입니다. 약속 클라이언트의 역할은 데이터를 제공하는 것입니다. 이 두 가지 역할을 혼합하는 것은 이해하거나 추론하기 어렵 프로그램으로 이어질 수 있습니다.

    약속의 특성은 미래를 확장하지 않는 이유 또한 요청할 수 있습니다. 이것은 (당신이 그것을 할 때마다 호출 약속 보장하지만에 명시 적으로 호출 미래에 가진 반면,이 업 캐스팅은 생략 할하는 경향이있다) 맹목적으로 그들이 미래에 대한 약속을 업 캐스팅해야 고객에게 약속을 통과 프로그래머를 억제하는 또 다른 디자인 결정이다. 즉, 약속을 반환하여 당신은 다른 사람에, 당신은 그것을에 가입 할 수있는 권리를주고있다 미래를 반환하여 완료 할 수있는 권리를주고있다.

    편집하다:

    당신이 선물에 대한 자세한 내용을 원하시면, 스칼라 책에서 학습 동시 프로그래밍 4 장 상세를 설명합니다. 면책 조항 : 나는이 책의 저자입니다.

  2. ==============================

    2.둘 사이의 차이는 약속 데이터를 중심으로하면서 미래 보통 중심 계산된다는 것이다.

    둘 사이의 차이는 약속 데이터를 중심으로하면서 미래 보통 중심 계산된다는 것이다.

    당신의 이해이 일치 보이지만, 제가 무엇을 의미하는지 설명하자 :

    (다른 기능 / 방법에 의해 리턴 제외) 모두 스칼라 및 Clojure의 미래 일부 연산으로 생성된다 :

    // scala
    future { do_something() }
    
    ;; clojure
    (future (do-something))
    

    두 경우 모두에서 미래의 "리턴 값은"단지 계산이 종료 된 후에 만 ​​(블로킹없이) 판독 할 수있다. 이러한 경우가되면 계산이 일부 배경 스레드 (풀)에서 실행될지기로 프로그래머의 제어 밖에 일반적이다.

    두 경우 모두 대조적으로 약속 나중에 (회만)을 채워 넣을 수있는 처음에 빈 용기입니다 :

    // scala
    val p = promise[Int]
    ...
    p success 10 // or failure Exception()
    
    ;; clojure
    (def p (promise))
    (deliver p 10) 
    

    이 경우 일단을 읽을 수 있습니다.

    선물과 약속을 읽는 것은 Clojure의에서 DEREF 통해 이루어집니다 (실현? DEREF이 차단 여부를 확인하는 데 사용할 수 있습니다). 스칼라에서 독서는 미래의 특성에 의해 제공되는 방법을 통해 이루어집니다. 우리는 따라서 미래를 구현하는 객체를 얻을 수있는 약속의 결과를 읽으려면,이 p.future하여 수행됩니다. 형질의 미래가 약속에 의해 구현되는 경우 이제 다음 p.future이를 반환 할 수 있으며, 두 사람은 동일하다. 이것은 순수하게 구현 선택과 개념을 변경하지 않습니다. 그래서 당신은 잘못하지 않았다! 어떤 경우에도 선물은 대부분 콜백을 사용하여 처리된다.

    이 시점에서 두 개념의 초기 특성을 재고 할 가치가있을 수 있습니다

    미래 어느 시점에 결과를 생성하는 연산을 나타낸다. 하나의 가능한 구현을 살펴 보자 : 우리는 어떤 스레드 (수영장)에서 코드를 실행하고 완료되면, 우리가 약속을 이행하기 위해 반환 값을 사용하여 배열합니다. 미래의 결과를 읽는 그래서 약속을 읽고; 이 사고 Clojure에서의 방법 (반드시 구현)입니다.

    반면에 약속은 어떤 점에서 채워집니다 값을 나타냅니다. 이 수단이 가득 도착하면 어떤 계산 결과를 생성한다는. 그래서 방법이 우리가 콜백을 사용하여 같은 방법으로 값을 소비해야하므로, 완료 미래 같다; 이 사고 스칼라의 방법입니다.

  3. ==============================

    3.후드 아래에 미래가 약속의 관점에서 구현되며,이 약속은 당신이 당신의 미래에 전달 된 몸으로 완료되었음을 참고 :

    후드 아래에 미래가 약속의 관점에서 구현되며,이 약속은 당신이 당신의 미래에 전달 된 몸으로 완료되었음을 참고 :

    def apply[T](body: =>T): Future[T] = impl.Future(body)  //here I have omitted the implicit ExecutorContext
    

    impl.Future 미래의 특성의 구현입니다 :

    def apply[T](body: =>T)(implicit executor: ExecutionContext): scala.concurrent.Future[T] =
    {
      val runnable = new PromiseCompletingRunnable(body)
      executor.prepare.execute(runnable)
      runnable.promise.future
    }
    

    어디 PromiseCompletingRunnable는 다음과 같습니다 :

    class PromiseCompletingRunnable[T](body: => T) extends Runnable {
    val promise = new Promise.DefaultPromise[T]()
    
    override def run() = {
      promise complete {
        try Success(body) catch { case NonFatal(e) => Failure(e) }
      }
    } }
    

    당신은 그들이 당신이 약속을 사용하지 않고 미래를 얻을 수없는 현실에서 독립적으로 사용을 할 수있는 별도의 개념이 비록 볼 수 있도록.

  4. from https://stackoverflow.com/questions/18960339/clarification-needed-about-futures-and-promises-in-scala by cc-by-sa and MIT license