Skip to content Skip to sidebar Skip to footer

How To Wait A Js Async Function From Golang Wasm?

I have written a little function await in order to handle async javascript function from go: func await(awaitable js.Value) (ret js.Value, ok bool) { if awaitable.Type() != js.

Solution 1:

You don't need goroutines for that one :D

I see a few problems in this code that doesn't make it idiomatic and can lead to some errors (some of which might lock your callback and lead to this situation you're describing):

  • You shouldn't close the done channel inside the handling function. This can lead to unwanted closing due to concurrencies and it's a bad practice in general.
  • Since there's no guarantee in the order of execution, changing external variables might lead to some concurrency problems. It's best to communicate with the external functions using channels only.
  • The results from onResolve and onCatch should use separate channels. This can lead to better handling of the outputs and sort out the results for the main function individually, ideally through a select statement.
  • There's no need for separate onReject and onCatch methods, since they are overlapping each other's responsibilities.

If I had to design this await function, I'd simplify it a bit to something like this:

funcawait(awaitable js.Value) ([]js.Value, []js.Value) {
    then := make(chan []js.Value)
    deferclose(then)
    thenFunc := js.FuncOf(func(this js.Value, args []js.Value)interface{} {
        then <- args
        returnnil
    })
    defer thenFunc.Release()

    catch := make(chan []js.Value)
    deferclose(catch)
    catchFunc := js.FuncOf(func(this js.Value, args []js.Value)interface{} {
        catch <- args
        returnnil
    })
    defer catchFunc.Release()

    awaitable.Call("then", thenFunc).Call("catch", catchFunc)

    select {
    case result := <-then:
        return result, nilcase err := <-catch:
        returnnil, err
    }
}

This would make the function idiomatic, as the function would return resolve, reject data, kinda like a result, err situation that is common in Go. Also a bit easier to deal with unwanted concurrencies since we don't handle variables in different closures.

Last but not least, make sure you're not calling both resolve and reject in your Javascript Promise, as the Release method in js.Func explicitly tells that you should not access such resources once they are released:

// Release frees up resources allocated for the function.// The function must not be invoked after calling Release.// It is allowed to call Release while the function is still running.

Post a Comment for "How To Wait A Js Async Function From Golang Wasm?"