kotlin의 coroutines에 대한 아이디어는 정지 및 콜백 개념을 추상화하고 간단한 순차 코드를 작성하는 것이 었습니다. 코 루틴이 일시 중단되었거나 스레드가 아닌 것처럼 걱정하지 않아도됩니다.COROTUTINE_SUSPENDED 및 Kotlin의 suspendCoroutineOrReturn
suspendCoroutineOrReturn
과 COROUTINE_SUSPENDED
의 목적은 무엇이며 어떤 경우에 사용합니까?
kotlin의 coroutines에 대한 아이디어는 정지 및 콜백 개념을 추상화하고 간단한 순차 코드를 작성하는 것이 었습니다. 코 루틴이 일시 중단되었거나 스레드가 아닌 것처럼 걱정하지 않아도됩니다.COROTUTINE_SUSPENDED 및 Kotlin의 suspendCoroutineOrReturn
suspendCoroutineOrReturn
과 COROUTINE_SUSPENDED
의 목적은 무엇이며 어떤 경우에 사용합니까?
suspendCoroutineOrReturn
및 COROUTINE_SUSPENDED
intrinsics는 매우 최근에 특정 스택 오버 플로우 문제를 해결하기 위해 1.1에서 소개되었습니다. 여기 은 예입니다
await
단순히 완성을 기다리는
fun problem() = async {
repeat(10_000) {
await(work())
}
}
:
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Unit {
f.whenComplete { value, exception -> // <- await$lambda
if (exception != null) c.resumeWithException(exception) else
c.resume(value)
}
}
것은 이제 work
이 정말로 중단하지 않는 경우를 살펴 보자하지만, (예를 들어, 즉시 결과를 반환 , 캐시 됨). problem$stateMachine
이 await
, CompletableFuture.whenComplete
, await$lambda
, ContinuationImpl.resume
, problem$stateMachine
, await
, ...
은 아무것도 없다 : 코 루틴은 코 틀린에로 컴파일하는 것입니다 상태 머신은 다음과 통화를 할 것입니다 이제까지 일시 중단되고 상태 머신은 같은 실행 스레드 내에서 반복적으로 자신을 호출하며, 이는 StackOverflowError
으로 끝납니다.
await
은 coroutine이 실제로 일시 중단되었는지 여부를 구별하기 위해 특수 토큰 (COROUTINE_SUSPENDED
)을 반환하여 상태 시스템이 스택 오버플로를 피할 수 있도록 허용하는 것이 좋습니다. 다음으로 코 루틴 실행을 제어하기 위해 suspendCoroutineOrReturn
이 있습니다. 그 선언은 다음과 같습니다.
연속으로 제공되는 블록을 수신합니다. 기본적으로 Continuation
인스턴스 인 에 액세스하는 방법이며 일반적으로 숨겨져 있으며 컴파일하는 동안에 만 나타납니다. 블록은 임의의 값 또는 COROUTINE_SUSPENDED
을 반환 할 수도 있습니다.
이 모든 것이 다소 복잡해 보입니다. Kotlin은이를 숨기려고 시도하고 위에서 언급 한 모든 것을 내부적으로 수행하는 suspendCoroutine
기능을 사용하도록 권장합니다. 여기 StackOverflowError
방지 올바른 await
구현입니다 (보조 노트 : await
가 코 틀린 lib 디렉토리에 제공됩니다, 그것은 실제로 확장 기능입니다,하지만이 토론이 중요하지 않아)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutine { c ->
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception) else
c.resume(value)
}
}
그러나 당신은 이제까지 먹고 싶어하는 경우 외부 연결이 이루어질 때마다 suspendCoroutineOrReturn
으로 전화하고 COROUTINE_SUSPENDED
을 반환해야합니다.