在 kotlin 1.3 中使用协程的正确方法

correct way of using coroutines in kotlin 1.3

我在 corotuines 还处于实验阶段时就开始使用它了。使用 anko,我有类似

的东西
async(UI) {
    val request = bg { sendRequest() }
    val result = request.await()
    // UI work
}

我真的很喜欢它的结构,它确实提供了比回调地狱 imo 更清晰的代码。我刚刚意识到协程现在处于稳定状态,迫不及待地想尝试一下。我更新了我的 kotlin 和 anko,现在我有了这个

doAsync {
    val result = sendRequest()
    uiThread {
        // ui work
    }
}

我做得对吗?这种结构对我来说似乎很难看。虽然它可能更具可读性,但我仍然喜欢调用 await() 的旧方法。或者我在这里想念什么?我记得引入 coroutines 时的卖点之一是少花括号。

你不需要 Anko 来获得带有协程的好代码。此外,您不需要 async 事实上,对于像您这样的情况,您应该避免使用它,您只想进行非阻塞调用并且不想同时启动多个此类调用。你的基本习语应该是

myScope.launch {
    val result = sendRequest()
    // UI work
}

其中 sendRequest()

suspend fun sendRequest() = withContext(Dispatchers.IO) { ... body ... }

如果您从 Android Activity 调用它,那么 myScope 可以只是隐式的 this,并且您的 activity 必须实现 CoroutineScope:

class MyActivity : AppCompatActivity, CoroutineScope {
    override val coroutineContext = SupervisorJob() + Dispatchers.Main
    ...
}

为了获得更多见解,强烈推荐阅读 Roman Elizarov 的 Explicit Concurrency