I'm trying to include a Go-WebAssembly function inside a JavaScript Web Worker, and the problem is that the event onmessage from the worker runs before the WebAssembly loads so everytime I call the WebAssembly function I got an error: "yourFunction is not defined". I hope you can help me figuring out how to solve this problem or you can give me ideas how to implement this. Thanks !
A simplified version of my code:
main.go
package main
import (
"fmt"
"log"
"syscall/js"
)
func myGoFunction(this js.Value, i []js.Value) interface{} {
//Do some hard work
fmt.Println(i[0])
return true
}
func main() {
js.Global().Set("myGoFunction", js.FuncOf(myGoFunction))
<-make(chan bool)
}
main.js
const doSomething = () => {
if (myArray.length > 0)
worker.postMessage({ value: myArray.shift() })
}
const init = () => {
if (worker) worker.terminate()
worker = new Worker('worker.js')
worker.postMessage({ a: A, b: B, bool: true })
worker.onmessage = doSomething
}
init()
worker.js
importScripts('wasm_exec.js');
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
onmessage = (e) => {
const {settings} = e.data
if (settings) {
//set some values
} else {
for (let i= 0; i < 1000000; i )
someArray[i] = calculate(i)
postMessage({someArray})
}
}
const calculate = (i) => {
//Do more
//Here is where I call the go function
myGoFunction(i)
}
Something I did to see if the myGoFunction is loading, is to put the WebAssembly.instantiateStreaming into a promise then call the onmessage but of course this will load the WebAssembly.instantiateStreaming millions of times and the job is done but extremely slow. Or maybe I implemented the promises the wrong way. I don't know, please help. :D
CodePudding user response:
You can store the promise returned from WebAssembly.instantiateStreaming()
and await it in your onmessage
handler:
const waInit = WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
onmessage = async (e) => {
await waInit; // now WA is ready
const {settings} = e.data
// The rest of your handler