Java 如何在后端控制器中使用Kotlin协程同时使用多个端点

Java 如何在后端控制器中使用Kotlin协程同时使用多个端点,java,kotlin,async-await,kotlin-coroutines,Java,Kotlin,Async Await,Kotlin Coroutines,上下文:我发现很少有教程解释如何同时使用Kotlin的多个端点,但它们是基于Android的,在我的例子中,它是一个后端应用程序。我有一些使用CompleteableFuture的经验,但我认为我应该使用Coroutine,因为它是一个Kotlin,并且没有Spring依赖性 根据一些建议,我达成了协议 @Singleton class PersonEndpoint() { @Inject lateinit var employeClient: EmployeClien

上下文:我发现很少有教程解释如何同时使用Kotlin的多个端点,但它们是基于Android的,在我的例子中,它是一个后端应用程序。我有一些使用CompleteableFuture的经验,但我认为我应该使用Coroutine,因为它是一个Kotlin,并且没有Spring依赖性

根据一些建议,我达成了协议

@Singleton
class PersonEndpoint()
    {

    @Inject
    lateinit var employeClient: EmployeClient

    override suspend fun getPersonDetails(request: PersonRequest): PersonResponse {
        var combinedResult: String

        GlobalScope.launch {
            val resultA: String
            val resultB: String

            val employeesA = async{ employeClient.getEmployeesA()}

            val employeesB = async{ employeClient.getEmployeesB()}

            try{

                combinedResult = employeesA.await() + employeesB.await()

                print(combinedResult)

            } catch (ex: Exception) {
                ex.printStackTrace()
            }

        // ISSUE 1
        if I try add return over here it is not allowed. 
        I understand it is working how it is designed to work: GlobalScope is running in different thread

        }
        
    // ISSUE 2
    if I try return combinedResult over here combinedResult isn't initialized.
    I understand it is working how it is designed to work: GlobalScope is running in different thread and I can
    debug and see that return over here executes earlier than employeesA.await = employeesB.await

}
那么,在返回到客户端之前,如何执行combinedResult=employeesA.await()+employeesB.await()

***在Denis/answer之后编辑

@Singleton
class CustomerEndpoint(){

    fun serve(): Collection<Int> {
        return runBlocking {
            async {
                getItemDouble(1)
            }
            async {
                getItemTriple(1)
            }
        }.map { it.await() }
    }

suspend fun getItemDouble(i: Int): Int {
    delay(1000)
    return i * 2
}

suspend fun getItemTriple(i: Int): Int {
    delay(1000)
    return i * 3
}

override suspend fun getPersonDetails(request: PersonRequest): PersonResponse {

    val result = serve()
    println("Got result $result")
    
    ...
}
@Singleton
类CustomerEndpoint(){
趣味服务():收藏{
返回运行阻塞{
异步的{
getItemDouble(1)
}
异步的{
getItemTriple(1)
}
}.map{it.await()}
}
暂停趣味getItemDouble(i:Int):Int{
延迟(1000)
返回i*2
}
暂停有趣的getItemTriple(i:Int):Int{
延迟(1000)
返回i*3
}
覆盖suspend fun getPersonDetails(请求:PersonRequest):PersonResponse{
val结果=serve()
println(“获得结果$result”)
...
}
导入kotlinx.coroutines.async
导入kotlinx.coroutines.delay
导入kotlinx.coroutines.runBlocking
导入kotlin.system.measureTimeMillis
主要内容(){
val durationMs=测量值{
val结果=serve()
println(“获得结果$result”)
}
println(“处理在$durationMs中完成”)
}
趣味服务():收藏{
返回运行阻塞{
(1..2)地图{
异步的{
getItem(it)
}
}.map{it.await()}
}
}
暂停趣味getItem(i:Int):Int{
延迟(1000)//模拟项目检索工作
返回i*2
}

注意,这里有两个嵌套调用-
getItem(1)
getItem(2)
。我们可以看到它们是并行执行的,因为总体运行时间约为1秒。

Denis,谢谢。如果必须并行调用不同的方法,您会怎么做?我编辑了上面的问题,以举例说明我的问题。这不会改变任何事情-我们仍有两个调用并行运行。您可以运行此代码并确保它是正确的仍然在1秒钟内执行-欢迎,Jim!关于协同路由的一个很酷的事情是,它们提供所谓的结构化并发,即如果一个协同路由失败,当前的协同路由上下文也会失败(所有同级协同路由都被取消)。因为协同路由上下文是分层的(例如,在这里我们在
runBlocking()中创建一个根上下文)和每个<代码> AycNo()/Case>创建了一个子上下文),整个执行结束。异常处理是通过TIG/catch进行的。作为可选选项,在那里添加一个额外的try/catch,不要在异常情况下停止,只是以防万一,一个关于结构化并发的链接-还有一个注意事项,正如您所说,协同路由将调用不同的端点,即I/O,这就是为什么使用它更好的原因。请随时检查相应的
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlin.system.measureTimeMillis

fun main() {
    val durationMs = measureTimeMillis {
        val result = serve()
        println("Got result $result")
    }
    println("The processing is done in $durationMs ms")
}

fun serve(): Collection<Int> {
    return runBlocking {
        (1..2).map {
            async {
                getItem(it)
            }
        }.map { it.await() }
    }
}

suspend fun getItem(i: Int): Int {
    delay(1000) // Emulate item retrieval work
    return i * 2
}