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

How consume multiple endpoints at same time using Kotlin Coroutine in a BackEnd Controller

上下文:我发现很少有教程解释如何同时使用 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()?

*** 丹尼斯/回答后编辑

@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")
    
    ...
}
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
}

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


2021 年 8 月 5 日编辑

private suspend fun myMethod(): List<Any> {
    return runBlocking {
        listOf(
            async { method1() },
            async { method2() }
        ).map { it.await() }
    }
}

method1 和 method2 是调用不同端点的方法。