Is it possible to call a Go WebAssembly function, other than main
, in Javascript?
Let me first show what I did. My Go functions are defined as follows:
package main
import "fmt"
func main() {
fmt.Println("it works!")
}
func add(a, b int) int {
return a + b
}
I can only invoke the main
function:
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);
which returns it works!
as expected.
However, whenever I try to invoke the add
function, I receive TypeError: Cannot read property 'add' of undefined at Welcome.getWasm
, because both result.exports
, result.instance.exports
do not contain my function. I also tried capitalizing the Go function, but at no avail.
Thus, I started wondering what could be a problem – is it even possible to call a random Go function from Javascript? Or can I only call the default main()
function?
To be able to compile it to WASM you need to add GOOS=js GOARCH=wasm to the build command. This tells Go to compile to a . wasm file.
Yes, it is totally possible to call JavaScript-functions from inside your running WebAssembly functions!
To use WebAssembly in JavaScript, you first need to pull your module into memory before compilation/instantiation. This article provides a reference for the different mechanisms that can be used to fetch WebAssembly bytecode, as well as how to compile/instantiate then run it.
Yes, it is possible. You can "export" a function to the global context (i.e. window in browser, global in nodejs):
js.Global().Set("add", js.FuncOf(addFunction))
Where "add" is the name that you can use to call the function from Javascript (window.add) and "addFunction" is a Go function in your Go code, next to your main.
Note that "addFunction" must follow that method signature:
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
}
After "go.run(result.instance);" you can run.
go.run(result.instance);
add(100,200);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With