[Day 25] parallel request ,談 coroutine

改成平行存取的方式之後,我們試看看存取abc 裡面的內容: ​

get("/") {
    val a = async { client.get<String>("http://127.0.0.1:8080/a") }
    val b = async { client.get<String>("http://127.0.0.1:8080/b") }
    val c = async { client.get<String>("http://127.0.0.1:8080/c") }
    client.close()
    call.respondText(a + b + c, contentType = ContentType.Text.Plain)
}

​ 這時,我們會看到錯誤訊息: ​

Type mismatch.
Required: String
Found: Job

​ 這是為什麼呢?這要說到 kotlin 的一個結構:coroutine。 ​ coroutine,又叫做協程,是許多現代語言都有的一個結構。他可以透過控制線程來達成非同步的邏輯運作,在 ktor 裡面也是很重要的部分。 ​ 其中一個 coroutine 的使用方式,是使用 asyncawait 函式,來實作線程的暫停和啟動。 ​ 我們昨天使用 async,來使程式運作到 val a = async { client.get<String>("http://127.0.0.1:8080/a") } 時,可以不用等資料回傳先往下運作。不過,我們並沒有等資料回傳,所以 a 取得的是 coroutine Job。 ​ 我們加上 await,改寫成 ​

get("/") {
    val a = async { client.get<String>("http://127.0.0.1:8080/a") }
    val b = async { client.get<String>("http://127.0.0.1:8080/b") }
    val c = async { client.get<String>("http://127.0.0.1:8080/c") }
    val result = a.await() + b.await() + c.await()
    client.close()
    call.respondText(result, contentType = ContentType.Text.Plain)
}

​ 這樣,我們就可以等到 client.get 的資料了。