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

面向JS的Kotlin Multiplatform SDK中suspend函数导出问题处理咨询

Kotlin Multiplatform SDK 向JavaScript导出suspend函数的处理方案

我们基于Kotlin Multiplatform开发了一款SDK,采用Ktor作为网络客户端处理所有网络请求与认证,适配Android、iOS及Web应用。目前Android和iOS平台集成使用正常,但向JavaScript导出SDK时,遇到suspend函数无法导出的问题。

需要导出的示例类如下:

class DocumentRepository(private val documentUseCase:GetDocumentUseCase) {

    suspend fun getDocumentById(docId:String): String? {
        var docContent:String? = null
        documentUseCase.getDocumentById(docId = docId).onSuccess {
            docContent = it
        }.onError {
            docContent = null
        }
        return docContent
    }
}

根据JetBrains官方说明,目前暂不支持直接向JavaScript导出suspend函数,相关问题可参考官方的KT-56281和KT-32619问题记录。

解决方法:将suspend函数包装为返回Promise的函数

由于JavaScript原生采用Promise处理异步逻辑,我们可以在Kotlin Multiplatform的JS目标代码中,为需要导出的类编写包装层,将suspend函数转换为返回Promise的普通函数:

// 仅在JS目标下编译的包装类
@JsExport
class JsDocumentRepository(private val delegate: DocumentRepository) {
    // 将suspend函数转换为返回Promise的函数
    fun getDocumentById(docId: String): Promise<String?> {
        return Promise { resolve, reject ->
            kotlinx.coroutines.GlobalScope.launch {
                try {
                    val result = delegate.getDocumentById(docId)
                    resolve(result)
                } catch (e: Exception) {
                    reject(e)
                }
            }
        }
    }
}

或者可以封装一个通用的扩展函数,用于将任意suspend函数转换为Promise:

// 通用扩展函数,转换suspend函数为Promise
fun <T> (suspend () -> T).asPromise(): Promise<T> {
    return Promise { resolve, reject ->
        kotlinx.coroutines.GlobalScope.launch {
            try {
                resolve(this@asPromise())
            } catch (e: Exception) {
                reject(e)
            }
        }
    }
}

// 包装类中使用扩展函数
@JsExport
class JsDocumentRepository(private val delegate: DocumentRepository) {
    fun getDocumentById(docId: String): Promise<String?> {
        return { delegate.getDocumentById(docId) }.asPromise()
    }
}

JavaScript端调用示例

在JavaScript中,即可像调用普通Promise函数一样使用包装后的类:

// 初始化包装类实例
const docRepo = new JsDocumentRepository(/* 传入对应的依赖实例 */);

// 调用异步方法
docRepo.getDocumentById("your-document-id")
  .then(documentContent => {
    console.log("文档内容:", documentContent);
  })
  .catch(error => {
    console.error("获取文档失败:", error);
  });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:52:40