面向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
相关产品推荐
相关产品推荐

