I am running a CPU-bound WASM function. How do I prevent it from blocking the UI thread?

Viewed 437

I have a Go function exposed in a .wasm file and accessible from JS:

app.computePrimes = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
    handler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        resolve := args[0]
        // Commented out because this Promise never fails
        //reject := args[1]

        // Now that we have a way to return the response to JS, spawn a goroutine
        // This way, we don't block the event loop and avoid a deadlock
        go func() {
            app.console.Call("log", "starting")

            for i := 2; i < 100000; i++ {
                if big.NewInt(int64(i)).ProbablyPrime(20) && i > 20000 {
                    app.console.Call("log", i)
                }
            }

            app.console.Call("log", "finishing")
            resolve.Invoke("Done")
        }()

        // The handler of a Promise doesn't return any value
        return nil
    })

    return js.Global().Get("Promise").New(handler)
})

Despite the fact that it returns a Promise and executes the CPU-bound part in a goroutine, on the Web side it feels like everything is running on the main UI thread. I have read a bit on the state of development of WWebAssembly, and it seems like multi-threaded workloads are not yet commonplace.

Is a Web worker the only preferred way to execute such tasks?

1 Answers
Related