【问题标题】:Is it possible to explicitly call an exported Go WebAssembly function from JS?是否可以从 JS 显式调用导出的 Go WebAssembly 函数?
【发布时间】:2019-10-17 06:48:52
【问题描述】:

是否可以在 Javascript 中调用除 main 之外的 Go WebAssembly 函数?

让我先展示一下我做了什么。我的 Go 函数定义如下:

package main

import "fmt"

func main() {
    fmt.Println("it works!")
}

func add(a, b int) int {
    return a + b
}

我只能调用main函数:

const go = new Go();

const data   = await fetch("http://localhost:3333/main.wasm");
const result = await WebAssembly.instantiateStreaming(data, go.importObject);

go.run(result.instance);

按预期返回it works!

但是,每当我尝试调用add 函数时,我都会收到TypeError: Cannot read property 'add' of undefined at Welcome.getWasm,因为result.exportsresult.instance.exports 都不包含我的函数。我也尝试过大写 Go 函数,但无济于事。

因此,我开始想知道可能是什么问题 - 甚至可以从 Javascript 调用随机 Go 函数吗? 或者我只能调用默认的 main() 函数吗?

【问题讨论】:

  • 我找到的唯一可行的解​​决方案是使add()成为一个全局JS函数,通过使用js.Global().Set("add", js.FuncOf(add)),并将add()签名更改为func add(this js.Value, args []js.Value) interface{},然后在a中使用add全局 JS 范围,在我看来,这是一种 dirty
  • 它有自己未解决的issue in Golang repo

标签: javascript go webassembly


【解决方案1】:

是的,这是可能的。您可以将函数“导出”到全局上下文(即浏览器中的窗口,nodejs 中的全局):

js.Global().Set("add", js.FuncOf(addFunction))

其中“add”是可用于从 Javascript (window.add) 调用函数的名称,“addFunction”是 Go 代码中的 Go 函数,位于 main 旁边。

请注意,“addFunction”必须遵循该方法签名:

package main

import (
    "syscall/js"
)

func addFunction(this js.Value, p []js.Value) interface{} {
    sum := p[0].Int() + p[1].Int()
    return js.ValueOf(sum)
}

func main() {
    c := make(chan struct{}, 0)

    js.Global().Set("add", js.FuncOf(addFunction))

    <-c
}

在“go.run(result.instance);”之后你可以跑了。

go.run(result.instance);
add(100,200);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-15
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 2017-10-21
    相关资源
    最近更新 更多