48. public interface Continuation<in T> {
}
public val context: CoroutineContext
public fun resume(value: T)
public fun resumeWithException(exception: Throwable)
50. suspend fun fetchUserDetail(id: String) {
// ...
switch (label) {
case 0:
val token = auth()
case 1:
val user = getUser(token, id)
case 2:
updateUserData(user)
}
}
51. fun fetchUserDetail(id: String) {
// ...
switch (label) {
case 0:
val token = auth()
case 1:
val user = getUser(token, id)
case 2:
updateUserData(user)
}
}
52. fun fetchUserDetail(id: String, cont: Continuation) {
switch ( label) {
case 0:
auth( )
case 1:
getUser(token, id )
case 2:
…
}
}
val sm = object : CoroutineImpl { ... }
sm.
sm
, sm
53. fun fetchUserDetail(id: String, cont: Contiunation) {
val sm = object : CoroutineImpl { ... }
switch (sm.label) {
case 0:
auth(sm)
case 1:
getUser(token, id, sm)
case 2:
…
}
}
54. fun fetchUserDetail(id: String, cont: Contiunation) {
val sm = object : CoroutineImpl { ... }
switch (sm.label) {
case 0:
sm.id = id
sm.label = 1
auth(sm)
…
}
}
55. fun fetchUserDetail(id: String, cont: Contiunation) {
val sm = object : CoroutineImpl { ... }
switch (sm.label) {
…
case 1:
val id = sm.id
val token = sm.result as String
sm.label = 2
getUser(token, id, sm)
…
}
56. fun fetchUserDetail(id: String, cont: Contiunation) {
val sm = object : CoroutineImpl {
fun resume(...) {
fetchUserDetail(null, this)
}
}
switch (sm.label) {
case 0:
…
}
}
57. fun fetchUserDetail(id: String, cont: Contiunation) {
val sm = cont as? ThisSM ?: object : CoroutineImpl {
fun resume(...) {
fetchUserDetail(null, this)
}
}
switch (sm.label) {
case 0:
…
}
}
58.
59.
60. public interface Continuation<in T> {
}
public val context: CoroutineContext
public fun resume(value: T)
public fun resumeWithException(exception: Throwable)
64. class DispatchedContinuation<in T> (
val dispatcher: CoroutineDispatcher,
val continuation: Continuation<T>
) : Continuation<T> by continuation {
override fun resume(value: T) {
dispatcher.dispatch(context, DispatchTask(...))
}
...
}
65. fun launchOnUiThread() {
launch(UI) {
delay(1000L)
...
}
}
/**
* Dispatches execution onto Android main UI thread
* and provides native [delay][Delay.delay] support.
*/
val UI =
HandlerContext(Handler(Looper.getMainLooper()), "UI")
66. fun main(args: Array<String>) = runBlocking<Unit> {
val jobs = arrayListOf<Job>()
jobs += launch(Unconfined) {
println("'Unconfined': I'm working in thread ${Thread.currentThread().name}")
}
jobs += launch(coroutineContext) {
println("'coroutineContext': I'm working in thread ${Thread.currentThread().name}")
}
jobs += launch(CommonPool) {
println("'CommonPool': I'm working in thread ${Thread.currentThread().name}")
}
jobs += launch(newSingleThreadContext("MyOwnThread")) {
println("'newSTC': I'm working in thread ${Thread.currentThread().name}")
}
jobs.forEach { it.join() }
}
67.
68.
69. fun main(args: Array<String>) = runBlocking<Unit> {
launch {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
}
delay(1300L) // just quit after delay
}
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
70. fun main(args: Array<String>) = runBlocking<Unit> {
val job = launch {
try {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
} finally {
println("I'm running finally")
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
main: I'm tired of waiting!
I'm running finally
main: Now I can quit.