Uncaught TypeError: this.resultContinuation_0 is undefined when trying to run a suspend function in Kotlin JS Browser onclick
Uncaught TypeError: this.resultContinuation_0 is undefined when trying to run a suspend function in Kotlin JS Browser onclick
我正在 Kotlin
开发一个 multi-platform RISC-V 模拟器,我已经被一个问题困了一个多星期了。我已经尝试了所有可以在网上找到的方法,但我没有成功。
为您提供一些背景信息:
我正在尝试将 this project (here you can download my code) to the VMB (virtual motherboard, here you can download the latest, not yet published version) via WebSockets
. I've already done the communication part and also tested it on the JVM
branch (I've also made another small Kotlin JS project 仅与通信部分的代码绑定,它工作正常,但由于某种原因,当我将所有内容放在一起时它就不起作用了)。它构建时没有任何错误,它甚至可以正常工作(扩展),直到我尝试连接到 VMB
,然后我在浏览器的控制台中收到一条错误消息 Uncaught TypeError: this.resultContinuation_0 is undefined
。我在这个问题上浪费了很多时间,我很确定这只是我遗漏的一些小东西(甚至可能是显而易见的)。
重现问题的步骤:
- 下载项目(您需要
venus
和 VMB
)
- 如果您的机器上没有
grunt
,请下载并安装
- 在
vmb
文件夹中双击 mother.exe
并确保点击电源按钮(它仅适用于 windows,抱歉)
- 打开
InteliJ
中的venus
项目,使用gradle
构建(IntelliJ
通常会自动将项目识别为gradle
)
- 构建完成后,在
venus
文件夹中打开一个Powershell
或cmd
和运行grut dist
- 结果现在应该在
out
目录中。
- 您可能需要
XAMPP
在本地服务器上托管文件,以防您获得 CORS Error
- 打开页面后,转到
Simulator
选项卡,然后单击 Assemble & Simulate from Editor
按钮。
- 您现在应该能够在控制台中看到错误。
非常感谢任何帮助,因为我已经在这个问题上停留了好几天了。谢谢!
编辑:
经过进一步挖掘,我注意到每当我调用 suspend
函数时都会出现问题 onclick
。
例如:
我在 Driver.kt
:
中创建了一个函数
@JsName("connect")
suspend fun connect() {
sim.connectToMotherboard()
}
其中 connectToMotherboard()
是一个挂起的函数,每当按下按钮时我都会调用它。
HTML:
<button class="button is-primary" onclick="driver.connect()">Connect to Motherboard</button>
这给了我与标题中提到的相同的错误。在我为开发人员下载 Firefox
之后,我收到了这条消息:
Uncaught TypeError: can't access property "context", this.resultContinuation_0 is undefined
好的,问题是我在 HTML 代码中调用了一些 @JSName
函数。像这样:
@JsName("doSomething")
suspend fun doSomething() {
// some code...
}
然后在我的 HTML 代码中有这样几行:
<button id="someButton" class="button" onclick="doSomething()">Click Me</button>
这里的关键是suspend
关键字。如果从 JS/HTML 调用“普通”函数,则没有问题,但不能从 HTML 调用 suspend
函数。它必须在 launch
块或 Coroutine
中,否则 Continuation
将是 null
。所以我将 kotlin
代码更改为如下内容:
val myButton = document.getElementById("someButton")
simulatorRunButton!!.addEventListener("click", {
launch(EmptyCoroutineContext) {
doSomething()
}
})
当然,在这样做之后我不得不从我的 HTML 对象中删除 onclick
部分,像这样:
<button id="someButton" class="button">Click Me</button>
我正在 Kotlin
开发一个 multi-platform RISC-V 模拟器,我已经被一个问题困了一个多星期了。我已经尝试了所有可以在网上找到的方法,但我没有成功。
为您提供一些背景信息:
我正在尝试将 this project (here you can download my code) to the VMB (virtual motherboard, here you can download the latest, not yet published version) via WebSockets
. I've already done the communication part and also tested it on the JVM
branch (I've also made another small Kotlin JS project 仅与通信部分的代码绑定,它工作正常,但由于某种原因,当我将所有内容放在一起时它就不起作用了)。它构建时没有任何错误,它甚至可以正常工作(扩展),直到我尝试连接到 VMB
,然后我在浏览器的控制台中收到一条错误消息 Uncaught TypeError: this.resultContinuation_0 is undefined
。我在这个问题上浪费了很多时间,我很确定这只是我遗漏的一些小东西(甚至可能是显而易见的)。
重现问题的步骤:
- 下载项目(您需要
venus
和VMB
) - 如果您的机器上没有
grunt
,请下载并安装 - 在
vmb
文件夹中双击mother.exe
并确保点击电源按钮(它仅适用于 windows,抱歉) - 打开
InteliJ
中的venus
项目,使用gradle
构建(IntelliJ
通常会自动将项目识别为gradle
) - 构建完成后,在
venus
文件夹中打开一个Powershell
或cmd
和运行grut dist
- 结果现在应该在
out
目录中。 - 您可能需要
XAMPP
在本地服务器上托管文件,以防您获得CORS Error
- 打开页面后,转到
Simulator
选项卡,然后单击Assemble & Simulate from Editor
按钮。 - 您现在应该能够在控制台中看到错误。
非常感谢任何帮助,因为我已经在这个问题上停留了好几天了。谢谢!
编辑:
经过进一步挖掘,我注意到每当我调用 suspend
函数时都会出现问题 onclick
。
例如:
我在 Driver.kt
:
@JsName("connect")
suspend fun connect() {
sim.connectToMotherboard()
}
其中 connectToMotherboard()
是一个挂起的函数,每当按下按钮时我都会调用它。
HTML:
<button class="button is-primary" onclick="driver.connect()">Connect to Motherboard</button>
这给了我与标题中提到的相同的错误。在我为开发人员下载 Firefox
之后,我收到了这条消息:
Uncaught TypeError: can't access property "context", this.resultContinuation_0 is undefined
好的,问题是我在 HTML 代码中调用了一些 @JSName
函数。像这样:
@JsName("doSomething")
suspend fun doSomething() {
// some code...
}
然后在我的 HTML 代码中有这样几行:
<button id="someButton" class="button" onclick="doSomething()">Click Me</button>
这里的关键是suspend
关键字。如果从 JS/HTML 调用“普通”函数,则没有问题,但不能从 HTML 调用 suspend
函数。它必须在 launch
块或 Coroutine
中,否则 Continuation
将是 null
。所以我将 kotlin
代码更改为如下内容:
val myButton = document.getElementById("someButton")
simulatorRunButton!!.addEventListener("click", {
launch(EmptyCoroutineContext) {
doSomething()
}
})
当然,在这样做之后我不得不从我的 HTML 对象中删除 onclick
部分,像这样:
<button id="someButton" class="button">Click Me</button>