【问题标题】:Using async func in Compose Web在 Compose Web 中使用异步函数
【发布时间】:2023-01-03 09:39:12
【问题描述】:

我应该在 Compose Web 中使用 Ktor 客户端。但是,由于异步/非异步问题,无法在 Compose Web 中调用它。 环境是IntelliJ IDEA制作的模板工程。

首先,我使用这个:

val client=HttpClient(Js){
    install(ContentNegotiation){
        json()
    }
}


suspend fun shorterCall(url:String):String{
    val response = client.get(SERVER_NAME) {
        contentType(ContentType.Application.Json)
        parameter("url", url)
    }
    return response.bodyAsText()
}

suspend fun main() {
    var i by mutableStateOf("")

    renderComposable(rootElementId = "root") {
        Div({ style {
            height(100.vh)
            margin(0.px)
            width(100.vw)
        } }) {
            Input(type = InputType.Url) {
                onInput {
                    val input=it.value.trim()
                    if(input.startsWith("http"))
                        i=shorterCall(input)
                    else
                        i="NaN"
                }
            }
            Text(i)
        }
    }
}

然后,我得到了那个错误:

Suspend function can be called only within a coroutine body.

所以,我尝试了另一个:

import kotlinx.coroutines.*

fun shorterCall(url:String):String{
    var ret:String
    suspend fun t():String {
        val response = client.get(SERVER_NAME) {
            contentType(ContentType.Application.Json)
            parameter("url", url)
        }
        return response.bodyAsText()
    }
    runBlocking{
        ret=t()
    }
    return ret
}


//main func is same as upper one.

然后,我得到了那个错误:

Unresolved reference: runBlocking

+编辑正文 1:当我使用 GlobalScope.launchjs("JSCode") 时,它会引发该错误:

e: Could not find "kotlin" in [/home/user/.local/share/kotlin/daemon]
e: java.lang.IllegalStateException: FATAL ERROR: Could not find "kotlin" in [/home/user/.local/share/kotlin/daemon]

(a lot of internal errors bellow)

【问题讨论】:

    标签: kotlin kotlin-coroutines ktor kotlin-js ktor-client


    【解决方案1】:

    您可以使用 GlobalScope.launch() 方法在浏览器环境中为请求启动作业:

    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.runtime.getValue
    import androidx.compose.runtime.setValue
    import io.ktor.client.*
    import io.ktor.client.engine.js.*
    import io.ktor.client.request.*
    import io.ktor.client.statement.*
    import io.ktor.http.*
    import kotlinx.coroutines.GlobalScope
    import kotlinx.coroutines.launch
    import org.jetbrains.compose.web.attributes.InputType
    import org.jetbrains.compose.web.css.*
    import org.jetbrains.compose.web.dom.*
    import org.jetbrains.compose.web.renderComposable
    
    fun main() {
        val client = HttpClient(Js) {}
        var i by mutableStateOf("")
    
        renderComposable(rootElementId = "root") {
            Div({
                style {
                    height(100.vh)
                    margin(0.px)
                    width(100.vw)
                }
            }) {
                Input(type = InputType.Url) {
                    onInput {
                        val input = it.value.trim()
    
                        if (input.startsWith("http")) {
                            GlobalScope.launch {
                                i = client.shorterCall(input)
                            }
                        } else {
                            i = "NaN"
                        }
                    }
                }
                Text(i)
            }
        }
    }
    
    suspend fun HttpClient.shorterCall(url: String): String {
        val response = get(url) {
            contentType(ContentType.Application.Json)
        }
        return response.bodyAsText()
    }
    

    【讨论】:

    • 它在调用 GlobalScope.launch 时生成:e: Could not find "kotlin" in [/home/user/.local/share/kotlin/daemon]e: java.lang.IllegalStateException: FATAL ERROR: Could not find "kotlin" in [/home/user/.local/share/kotlin/daemon]
    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    相关资源
    最近更新 更多