是否可以从 JS 显式调用导出的 Go WebAssembly 函数?

krl*_*rlc 8 javascript go webassembly

是否可以main在 Javascript 中调用 Go WebAssembly 函数,而不是?

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

package main

import "fmt"

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

func add(a, b int) int {
    return a + b
}
Run Code Online (Sandbox Code Playgroud)

我只能调用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);
Run Code Online (Sandbox Code Playgroud)

it works!按预期返回。

然而,每当我试图调用add函数,我收到TypeError: Cannot read property 'add' of undefined at Welcome.getWasm,因为这两个result.exportsresult.instance.exports不包含我的功能。我也尝试将 Go 函数大写,但无济于事。

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

jor*_*gos 6

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

js.Global().Set("add", js.FuncOf(addFunction))
Run Code Online (Sandbox Code Playgroud)

其中“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
}
Run Code Online (Sandbox Code Playgroud)

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

go.run(result.instance);
add(100,200);
Run Code Online (Sandbox Code Playgroud)