标记功能暂停或使用构建器
Mark function suspend or using builder
我从 Android 应用程序中的协程开始。我正在重写 suspendCoroutine<> {}
的回调,但我遇到了一个难题:我什么时候应该将函数标记为 suspend
,什么时候应该将调用包装在某个构建器中(launch
, async
, 等等)?
是否有一些最佳实践、经验法则等?
您应该为当前正在进行的每个基于回调的异步 API 调用编写一个 suspend fun
。
您应该在进行的每个同步 API 调用中包含 withContext(myThreadPool)
。
所有 Android-友好 API 的 I/O 使用异步方法,因此对于这些,您将编写 suspend fun
,但对于 CPU 您可能需要 withContext
.
的密集型任务(例如解码图像)
最后,为了能够使用任何一种调用,您必须使用 launch(UI)
创建一个顶级协程。
请记住,以上只是一个经验法则。当你考虑你的代码时,很多时候你意识到你需要一个 suspend fun
来进行 CPU 密集型操作,因为在那个调用路径上的某个地方有一个 withContext
。
让我再补充一个关于协程 API 的典型误用的警告:你几乎不需要 async-await
。仅在您想要真正 运行 它 "in the background" 的情况下使用它,同时您继续在当前上下文中执行其他操作。简单来说,你永远不应该写
val result = async { calculation() }.await()
你应该写成
val result = withContext(myThreadPool) { calculation() }
我从 Android 应用程序中的协程开始。我正在重写 suspendCoroutine<> {}
的回调,但我遇到了一个难题:我什么时候应该将函数标记为 suspend
,什么时候应该将调用包装在某个构建器中(launch
, async
, 等等)?
是否有一些最佳实践、经验法则等?
您应该为当前正在进行的每个基于回调的异步 API 调用编写一个 suspend fun
。
您应该在进行的每个同步 API 调用中包含 withContext(myThreadPool)
。
所有 Android-友好 API 的 I/O 使用异步方法,因此对于这些,您将编写 suspend fun
,但对于 CPU 您可能需要 withContext
.
最后,为了能够使用任何一种调用,您必须使用 launch(UI)
创建一个顶级协程。
请记住,以上只是一个经验法则。当你考虑你的代码时,很多时候你意识到你需要一个 suspend fun
来进行 CPU 密集型操作,因为在那个调用路径上的某个地方有一个 withContext
。
让我再补充一个关于协程 API 的典型误用的警告:你几乎不需要 async-await
。仅在您想要真正 运行 它 "in the background" 的情况下使用它,同时您继续在当前上下文中执行其他操作。简单来说,你永远不应该写
val result = async { calculation() }.await()
你应该写成
val result = withContext(myThreadPool) { calculation() }