You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin/JS中正确导入并使用JavaScript异步函数?解决调用后返回Promise而非预期字符串的问题

问题分析与解决方案

你遇到的问题核心在于Kotlin/JS 不会自动将 JavaScript 的 Promise 转换为协程的挂起函数返回值,即使你给外部函数标记了 suspend。JavaScript 的 async 函数本质上是返回一个 Promise,而 Kotlin 的 suspend 修饰符只是标记函数是协程挂起函数,并没有处理 Promise 到协程的自动适配。

错误原因拆解

你当前的外部函数声明:

external object FirebasePorts{
 suspend fun signUp(email: String, password: String) : String
}

这里的 suspend 对 Kotlin/JS 的外部函数来说没有特殊意义——JS 的 signUp 返回的是 Promise,Kotlin 无法直接将其解析为 String,所以你拿到的还是原始的 Promise 对象。

正确的解决步骤

1. 修正外部函数的返回类型

首先,将外部函数的返回类型改为 Kotlin/JS 对应的 Promise<String>,明确它返回的是一个异步 Promise:

@JsModule("@jlengrand/firebase-ports")
@JsNonModule
external object FirebasePorts {
    fun signUp(email: String, password: String): Promise<String>
}

2. 在协程中使用 await() 解析 Promise

Kotlinx-coroutines-js 库提供了 await() 扩展函数,可以将 Promise 转换为协程的挂起调用,获取最终的返回值。确保你的项目已经引入了 kotlinx-coroutines-js 依赖,然后修改调用代码:

var user : String? by mutableStateOf(null)
Button(
 attrs = {
  onClick {
   GlobalScope.launch {
    try {
     // 用 await() 等待 Promise 完成并获取结果
     user = FirebasePorts.signUp(email, password).await()
    } catch (e: Exception) {
     // 处理 JS 函数中抛出的错误(比如注册失败)
     println("注册失败: $e")
    }
   }
  }
 }) {
 Text("Sign Up!")
}
TextArea(value = user.toString())

3. 可选:包装为 Suspend 函数(更优雅的调用)

如果你希望调用时更像 Kotlin 原生的挂起函数,可以自己封装一层:

// 给 FirebasePorts 添加扩展的 suspend 函数
suspend fun FirebasePorts.signUpSuspend(email: String, password: String): String {
    return signUp(email, password).await()
}

之后调用就可以直接用:

user = FirebasePorts.signUpSuspend(email, password)

额外注意点

  • 错误处理:你的 JS 函数里有 try/catch,但如果 createUserWithEmailAndPassword 失败,Promise 会被 reject,此时 Kotlin 调用 await() 会抛出异常,所以一定要在协程里添加 try/catch 处理错误。
  • 依赖检查:确保 build.gradle.kts 中包含 kotlinx-coroutines-js 依赖:
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-js:1.7.3")
    

内容的提问来源于stack exchange,提问作者jlengrand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 17:22:28