如何:在 Kotlin 中触发和忘记异步协程

She*_*rms 6 asynchronous coroutine kotlin

我一直在阅读 Kotlin 协同程序,但没有找到特定问题的答案。

假设我想迭代一个集合,为每个元素进行 API 调用(在这种特殊情况下,将文件推送到 Amazon S3)。我希望这些调用由异步协程处理,以免在等待时阻塞底层线程。

我不需要请求的返回值,只需要记录异常。

我将如何创建一个“即发即忘”的异步协程来发出这些请求之一?

Pau*_*cía 8

请注意,如果不存在特定的协程作用域(即不是挂起函数),您可以使用:

fun Process (item: String): Response {
    GlobalScope.launch {
       ... <YOUR ASYNC (Processing) CODE GOES HERE> ...
    }
    ... <YOUR SYNC CODE GOES HERE> ...
    return Response("Your request for $item is being processed...")
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以返回一个快速答案(充当确认),表明它已收到并且您正在处理它,而不会以 Fire&Forget 方式阻止客户端/消费者。

但是,例如,当异步部分引发异常时,请小心可能的内存泄漏。扩展 CoroutineScope 是一种更好的方法。更多信息请访问https://discuss.kotlinlang.org/t/unavoidable-memory-leak-when-using-coroutines/11603/7以及为什么不使用 GlobalScope.launch?


hol*_*ava -1

也许kotlinx.coroutines#launchkotlinx.coroutines#async可以满足您的需求。举些例子:

launch(CommonPool) {
    for(item in collection){
      val result = apiCall(item);
      log(result);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者

for(item in collection){
    launch(CommonPool) {
      val result = apiCall(item)
      log(result)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `launch` 必须放置在协程作用域内。创建作用域的典型方法是阻塞:`runBlocking`运行一个新的协程并中断地阻塞当前线程直到其完成,`coroutineScope`和`withContext`是挂起函数,OP希望避免挂起。我相信OP想要实现类似于Java执行器的东西,你可以简单地写:`executor.submit(job)`然后忘记。 (9认同)
  • 如果您没有办法创建非阻塞作用域,那么这就是一个无解的答案。 (5认同)