I am looking to integrate indexdb in a wasm based app. How do you “await” in a go function a promise from a js function. Here is the example
async getItem(key) { try{ const out = await database.getItem(key); return out; }catch(err){ return null; } }
and in go
func Get(key string)[]byte{ found := js.Global().Get("Store").Call('getItem', key ) // await for found // convert js.Value to to []byte return nil }
Async callbacks are fine too.
LE: one bad solution would be to create a go routine with an infinite loop waiting until a DOM variable exists like global.solution+ID to be set. But I believe this is a bad solution
Advertisement
Answer
You can use the then
method from the Promise
object to wait for the result, something like this:
package main import ( "fmt" "syscall/js" ) func main() { wait := make(chan interface{}) js.Global().Call("sayHello", 5000).Call("then", js.FuncOf(func(this js.Value, args []js.Value) interface{} { fmt.Println(args[0]) wait <- nil return nil })) <-wait fmt.Println("we're done here") }
Notice that we are using a channel to actually wait in the Go code. We need to do that because the Go program must still be running while receiving the callback from Javascript.
The index.html
file:
<html> <head> <meta charset="utf-8"/> <script src="wasm_exec.js"></script> <script> const go = new Go(); WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => { go.run(result.instance); }); function sayHello(time) { return new Promise(resolve => { console.log('waiting %dms and resolving', time) setTimeout(() => resolve('hola!'), time) }) } </script> </head> <body></body> </html>