Have been programming in Go from quite some time, and started looking into WebAssembly lately. While most of the things are straightforward, have a question around translating some of the Go specific constructs like channels and goroutines to wasm. Do they behave in the same way when used from JS as they would in Go (e.g. goroutines are exposed as async functions to JS, etc.)?
The WASM target of the go compiler does not currently support threads, or as Go calls them "procs".
This means that, from the perspective of a user of the language and simplifying a bit, a Go program running on WASM behaves as a Go program running with GOMAXPROCS=1
on any other platform.
Crucially, as long as you use proper synchronization in your code, nothing should change from a correctness standpoint. This includes the semantics of channels and goroutines, in the same way these semantics do not change when you run your code with GOMAXPROCS=1
.
The way this works is by including the go runtime (and its scheduler) in the built WASM module. The go runtime, exactly like in the case of GOMAXPROCS=1
is able to multiplex execution of multiple goroutines even if only a single thread/proc is available. Note that as goroutines are green threads, the go runtime is able to suspend them when they block (e.g. waiting for I/O or to acquire a lock) and execute other goroutines that are not blocked. Once a goroutine becomes unblocked (e.g. because the I/O operation has completed, or the lock became available) it is queued again for execution and resumes from where it left off.