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。我在这个问题上浪费了很多时间,我很确定这只是我遗漏的一些小东西(甚至可能是显而易见的)。

重现问题的步骤:

  1. 下载项目(您需要 venusVMB
  2. 如果您的机器上没有grunt,请下载并安装
  3. vmb 文件夹中双击 mother.exe 并确保点击电源按钮(它仅适用于 windows,抱歉)
  4. 打开InteliJ中的venus项目,使用gradle构建(IntelliJ通常会自动将项目识别为gradle
  5. 构建完成后,在venus文件夹中打开一个Powershellcmd和运行grut dist
  6. 结果现在应该在 out 目录中。
  7. 您可能需要 XAMPP 在本地服务器上托管文件,以防您获得 CORS Error
  8. 打开页面后,转到 Simulator 选项卡,然后单击 Assemble & Simulate from Editor 按钮。
  9. 您现在应该能够在控制台中看到错误。

非常感谢任何帮助,因为我已经在这个问题上停留了好几天了。谢谢!

编辑:

经过进一步挖掘,我注意到每当我调用 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>