go wasm impl simple await raise error“fatal error:all goroutines are asleep - deadlock!”

u4vypkhs  于 5个月前  发布在  Go
关注(0)|答案(1)|浏览(32)

下面是我的代码

package main

import (
    "fmt"
    "syscall/js"
)

func main() {
    js.Global().Set("testMethInWasm", js.FuncOf(func(this js.Value, args []js.Value) any {
        r := Await(js.Global().Call("eval", `Promise.resolve(true)`))
        fmt.Println(fmt.Sprintf("result:%v", r))
        return nil
    }))
    select {}
}

func Await(p js.Value) js.Value {
    var done = make(chan int)
    var r js.Value
    p.Call("then", js.FuncOf(func(this js.Value, args []js.Value) any {
        r = args[0]
        done <- 0
        return nil
    }))
    <-done
    return r
}

字符串
它会引发错误:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select (no cases)]:
main.main()
    /home/roroco/Dropbox/mix/go_wasm/test/wasm/testwasm/main.go:14 +0x4

goroutine 6 [chan receive]:
main.Await({{}, 0x7ff8000100000011, 0x410070})
    /home/roroco/Dropbox/mix/go_wasm/test/wasm/testwasm/main.go:25 +0xc
main.main.func1({{}, 0x0, 0x0}, {0x127068, 0x0, 0x0})
    /home/roroco/Dropbox/mix/go_wasm/test/wasm/testwasm/main.go:10 +0x3
syscall/js.handleEvent()
    /home/roroco/.goenv/versions/1.20.4/src/syscall/js/func.go:94 +0x26
exit code:
2

bis0qfac

bis0qfac1#

我发现def sync meth和在sync meth中运行<-done会引发这个错误,关键是,在go func(不是main goroutine)中运行<-done时,它工作得很好,我猜这是因为Chrome或go不允许wasm冻结主线程
所以我impl js async function like syntax,impl js async function like syntax,

package main

import (
    "fmt"
    "syscall/js"
)

func main() {
    js.Global().Set("testMethInWasm", AsyncFunc(func(this js.Value, args []js.Value) any {
        var r = Await(js.Global().Call("eval", `Promise.resolve(true)`))
        fmt.Println(fmt.Sprintf(`result:%v`, r))
        return r
    }))
    select {}
}

func AsyncFunc(fn func(this js.Value, args []js.Value) any) js.Func {
    return js.FuncOf(func(this js.Value, args []js.Value) any {
        return js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, args []js.Value) any {
            var resolve = args[0]
            go func() {
                resolve.Invoke(fn(this, args))
            }()
            return nil
        }))
    })
}

func Await(p js.Value) js.Value {
    var r js.Value
    var dc = make(chan int)
    p.Call("then", js.FuncOf(func(this js.Value, args []js.Value) any {
        r = args[0]
        dc <- 0
        return nil
    }))
    <-dc
    return r
}

字符串

相关问题