# Kotlin Coroutine 入门(二) - launch/async


## Kotlin 协程入门(二) - launch/async

这篇文章是从上一篇文章挂起的, 建议先看上一篇文章: [Kotlin Coroutine 入门](/211001-coroutine/)

我们都知道 suspend 只能在 suspend 函数中使用, 而如果不使用这种方式, 我们往往需要这样做:

```kotlin
lifecycleScope.launch {} // Android lifecycleScope
lifecycleScope.async {}
GlobalScope.launch {}
GlobalScope.async {}
```

在上一篇文章中我们可以了解到, `suspend () -> Int` 类型在字节码中会转换为 `(Continuation) -> Any?`, 因此 `launch/async` 函数实际上就是提供了一个 `Continuation` 对象

不管是 launch 还是 async, 他们提供的 `Continuation` 对象都是 `AbstractCoroutine`, 这就是顶层 `Cortinuation` 的由来, 他们的 resumeWith 方法就是:

```kotlin
public final override fun resumeWith(result: Result<T>) {
    val state = makeCompletingOnce(result.toState())
    if (state === COMPLETING_WAITING_CHILDREN) return
    afterResume(state)
}

protected open fun afterResume(state: Any?): Unit = afterCompletion(state)
protected open fun afterCompletion(state: Any?) {}
```

最终调用了 `afterCompletion`, 而它的具体实现其实只有三个类:

> 1. `DispatchedCoroutine`: `withContext` 方法创建出来的, 会阻塞当前协程, 在 `withContext` 中的耗时任务完成之后, 便会继续执行后续任务.
> 2. `BlockingCoroutine`: `runBlocking` 方法创建出来的, 不过它可以运行在非 suspend 函数中, 但是不同于 launch/async, 它会直接阻塞当前方法的执行, launch/async 则是启动了新的协程去干这件事
> 3. `ScopeCoroutine`: 也是由 `withContext` 创建出来的, 当 `withContext` 与调用之前的 `CoroutineContext` 一致的时候, 会使用这条快速路径

此时, 我们了解到了顶层协程的启动方式, 我们就可以继续了解 `Continuation` 在 suspend 中具体是怎么做到的挂起: [Kotlin Coroutine 入门 #4-suspend-的实现](http://localhost:1313/211001-coroutine/#4-suspend-的实现)


