scala.concurrent.Promise의 사용 사례는 무엇입니까?
저는 SIP-14를 읽고 있으며 개념 Future
이 완벽하고 이해하기 쉽습니다. 그러나 다음에 대해 두 가지 질문이 있습니다 Promise
.
SIP는 말한다
Depending on the implementation, it may be the case that p.future == p
. 어떻게 이럴 수있어? 인가Future
와Promise
서로 다른 두 가지 종류가 있지?우리는 언제 사용해야
Promise
합니까? 예제producer and consumer
코드 :import scala.concurrent.{ future, promise } val p = promise[T] val f = p.future val producer = future { val r = produceSomething() p success r continueDoingSomethingUnrelated() } val consumer = future { startDoingSomething() f onSuccess { case r => doSomethingWithResult() } }
읽기 쉽지만 그렇게 써야하나요? 나는 다음과 같이 미래와 약속없이 그것을 구현하려고했습니다.
val f = future {
produceSomething()
}
val producer = future {
continueDoingSomethingUnrelated()
}
startDoingSomething()
val consumer = future {
f onSuccess {
case r => doSomethingWithResult()
}
}
이것과 주어진 예의 차이점은 무엇이며 약속이 필요한 이유는 무엇입니까?
약속과 미래는 상호 보완적인 개념입니다. 미래는 언젠가 검색 될 가치이며 그 사건이 발생했을 때 그것을 가지고 무언가를 할 수 있습니다. 따라서 이는 계산의 읽기 또는 출력 끝점이며 값을 검색하는 것입니다.
Promise는 유사하게 계산의 작성 측면입니다. 당신은 계산의 결과를 넣을 장소 인 promise를 만들고 그 약속으로부터 약속에 넣은 결과를 읽는 데 사용될 미래를 얻습니다. 실패 또는 성공으로 Promise를 완료하면 연결된 Future에 연결된 모든 동작이 트리거됩니다.
첫 번째 질문과 관련하여 우리가 가진 약속 p에 대해 어떻게 될 수 있습니까 p.future == p
? 이것은 단일 항목 버퍼 (처음에는 비어있는 컨테이너)와 같이 상상할 수 있으며, 나중에 내용이 영원히 내용이 될 하나의 값을 저장할 수 있습니다. 이제 여러분의 관점에 따라 이것은 약속이자 미래입니다. 버퍼에 값을 쓰려는 사람에게는 약속입니다. 그 값이 버퍼에 들어가기를 기다리는 사람에게는 미래입니다.
특히 Scala 동시 API의 경우 여기 에서 Promise 특성을 살펴보면 Promise 컴패니언 객체의 메서드가 구현되는 방식을 볼 수 있습니다.
object Promise {
/** Creates a promise object which can be completed with a value.
*
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
def apply[T](): Promise[T] = new impl.Promise.DefaultPromise[T]()
/** Creates an already completed Promise with the specified exception.
*
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
def failed[T](exception: Throwable): Promise[T] = new impl.Promise.KeptPromise[T](Failure(exception))
/** Creates an already completed Promise with the specified result.
*
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
def successful[T](result: T): Promise[T] = new impl.Promise.KeptPromise[T](Success(result))
}
Now, those implementation of promises, DefaultPromise and KeptPromise can be found here. They both extend a base little trait which happens to have the same name, but it is located in a different package:
private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] {
def future: this.type = this
}
So you can see what they mean by p.future == p
.
DefaultPromise
is the buffer I was referring above, while KeptPromise
is a buffer with the value put in from its very creation.
Regarding your example, the future block you use there actually creates a promise behind the scenes. Let's look at the definition of future
in here :
def future[T](body: =>T)(implicit execctx: ExecutionContext): Future[T] = Future[T](body)
By following the chain of methods you end up in the impl.Future:
private[concurrent] object Future {
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) }
}
}
}
def apply[T](body: =>T)(implicit executor: ExecutionContext): scala.concurrent.Future[T] = {
val runnable = new PromiseCompletingRunnable(body)
executor.execute(runnable)
runnable.promise.future
}
}
So, as you can see, the result you get from your producer block gets poured into a promise.
LATER EDIT:
Regarding the real-world use: Most of the time you won't deal with promises directly. If you'll use a library which performs asynchronous computation then you'll just work with the futures returned by the library's methods. Promises are, in this case, created by the library - you're just working with the reading end of what those methods do.
But if you need to implement your own asynchronous API you'll have to start working with them. Suppose you need to implement an async HTTP client on top of, lets say, Netty. Then your code will look somewhat like this
def makeHTTPCall(request: Request): Future[Response] = {
val p = Promise[Response]
registerOnCompleteCallback(buffer => {
val response = makeResponse(buffer)
p success response
})
p.future
}
참고URL : https://stackoverflow.com/questions/13381134/what-are-the-use-cases-of-scala-concurrent-promise
'programing tip' 카테고리의 다른 글
스톱워치 대 System.DateTime.Now를 사용하여 타이밍 이벤트 (0) | 2020.09.04 |
---|---|
일부 플랫폼에서는 char **, 다른 플랫폼에서는 const char **를받는 C ++ 함수를 이식 가능하게 호출 할 수있는 방법은 무엇입니까? (0) | 2020.09.04 |
except 블록을 테스트하기 위해 Exception을 발생시키는 함수 모킹 (0) | 2020.09.04 |
xml을 사용하여 Android TextView에서 사용자 정의 글꼴 사용 (0) | 2020.09.04 |
2 단계 인증을 사용하여 https를 통해 GitHub에서 Git 클론 (0) | 2020.09.04 |