在默认的 Promise 构造函数中使用 Kotlin JS 中返回动态的 JS 函数会导致 ClassCastException
Using JS function returning dynamic in Kotlin JS within the default Promise constructor results in ClassCastException
我在尝试将 gapi
调用转换为 Promises 时遇到此错误,但我想调用其他函数可能会导致相同的问题。首先,我在页面中将库作为脚本添加:
script(src = "https://apis.google.com/js/platform.js") {
async = true
defer = true
}
接下来,我从 window
中获取了 gapi
对象:
import kotlinx.browser.window
import org.w3c.dom.get
val gapi = window["gapi"]
最后,我像这样使用 load
函数:
import kotlin.js.Promise
fun loadGapi() = Promise<Unit> { resolve, _ ->
gapi.load("client:auth2") { resolve(Unit) }
}
在 IDE 中给我一个警告:
这导致在页面内调用时出现以下错误:
Uncaught (in promise) ClassCastException {message: undefined, cause: undefined, name: 'ClassCastException', stack: 'ClassCastException\n at THROW_CCE (http://localh… (http://localhost:3000/static/app.js:4930:14)'}
不确定为什么会这样。我尝试用已评估的 JS 代码重现该问题,但无济于事:
import kotlin.js.Promise
fun loadGapi(): Promise<Any> {
val functionReturningUndefined =
js("function (resolve) { resolve('test'); return undefined; }")
return Promise { resolve, _ ->
functionReturningUndefined { param -> resolve(param as Any) } as Unit
}
}
无论如何,忽略函数的 return 值并添加 return@Promise Unit
即可解决问题,如下所示:
fun loadGapi() = Promise<Unit> { resolve, _ ->
gapi.load("client:auth2") { resolve(Unit) }
return@Promise Unit
}
或者,可以添加专门针对 dynamic
return 类型的扩展函数(我把我的放在 shared/Promises.kt
中):
fun <T> Promise(executor: (resolve: (T) -> Unit, reject: (Throwable) -> Unit) -> dynamic) =
Promise<T> { resolve, reject ->
executor(resolve, reject)
Unit
}
然后简单地:
import shared.Promise
fun loadGapi() = Promise<Unit> { resolve, _ ->
gapi.load("client:auth2") { resolve(Unit) }
}
我在尝试将 gapi
调用转换为 Promises 时遇到此错误,但我想调用其他函数可能会导致相同的问题。首先,我在页面中将库作为脚本添加:
script(src = "https://apis.google.com/js/platform.js") {
async = true
defer = true
}
接下来,我从 window
中获取了 gapi
对象:
import kotlinx.browser.window
import org.w3c.dom.get
val gapi = window["gapi"]
最后,我像这样使用 load
函数:
import kotlin.js.Promise
fun loadGapi() = Promise<Unit> { resolve, _ ->
gapi.load("client:auth2") { resolve(Unit) }
}
在 IDE 中给我一个警告:
这导致在页面内调用时出现以下错误:
Uncaught (in promise) ClassCastException {message: undefined, cause: undefined, name: 'ClassCastException', stack: 'ClassCastException\n at THROW_CCE (http://localh… (http://localhost:3000/static/app.js:4930:14)'}
不确定为什么会这样。我尝试用已评估的 JS 代码重现该问题,但无济于事:
import kotlin.js.Promise
fun loadGapi(): Promise<Any> {
val functionReturningUndefined =
js("function (resolve) { resolve('test'); return undefined; }")
return Promise { resolve, _ ->
functionReturningUndefined { param -> resolve(param as Any) } as Unit
}
}
无论如何,忽略函数的 return 值并添加 return@Promise Unit
即可解决问题,如下所示:
fun loadGapi() = Promise<Unit> { resolve, _ ->
gapi.load("client:auth2") { resolve(Unit) }
return@Promise Unit
}
或者,可以添加专门针对 dynamic
return 类型的扩展函数(我把我的放在 shared/Promises.kt
中):
fun <T> Promise(executor: (resolve: (T) -> Unit, reject: (Throwable) -> Unit) -> dynamic) =
Promise<T> { resolve, reject ->
executor(resolve, reject)
Unit
}
然后简单地:
import shared.Promise
fun loadGapi() = Promise<Unit> { resolve, _ ->
gapi.load("client:auth2") { resolve(Unit) }
}