You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go WASM环境下js.FuncOf回调内调用http.Get仍死锁如何解决?

问题成因

  1. 核心死锁原因:你虽然把http.Get放到了单独goroutine中执行,但紧接着在js.FuncOf注册的JS回调函数内部用<-done做了阻塞操作。JS本身是单线程运行的,所有异步API(包括http.Get底层依赖的fetch、IndexedDB操作)的回调都需要等待浏览器事件循环空闲时才能执行。而你在onupgradeneeded的回调里阻塞等待通道结果,会直接卡住JS事件循环,导致http.Get的请求结果永远无法返回,通道永远没有数据写入,形成死锁。
  2. 附加报错原因:从错误日志可以看到主goroutine提前退出,WASM程序主函数如果没有加阻塞逻辑,初始化完成后会直接销毁runtime,后续异步事件触发时就会抛出Go program has already exited的错误。

解决方案

  1. 不要在js.FuncOf注册的回调中执行任何阻塞操作,把HTTP请求、后续写入IndexedDB的逻辑全部放到单独的goroutine中,JS回调执行完直接返回,不要等待异步操作结果。
  2. 在main函数末尾添加阻塞逻辑,保证WASM程序不会提前退出。

修正后的代码示例

func (db *DataBase) init(dataSet, table string) {
    var Ok, Err, Upgrade js.Func
    db.Request = Window.Get("indexedDB").Call("open", dataSet, 1)

    Upgrade = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        defer Upgrade.Release()
        db.Data = this.Get("result")
        fullUrlFile := "https://i.imgur.com/m1UIjW1.jpg"

        // 所有异步逻辑全部放到goroutine中,回调直接返回不阻塞
        go func(fullUrlFile string) {
            var blob *bytes.Buffer
            r, e := http.Get(fullUrlFile)
            if e != nil {
                panic(e)
            }
            defer r.Body.Close()
            buildFileName()
            
            var dest []byte
            blob = bytes.NewBuffer(dest)
            io.Copy(blob, r.Body)

            // 写入IndexedDB的逻辑移到goroutine内部
            Store := db.Data.Call("createObjectStore", table, map[string]interface{}{"keyPath": "id"}) 
            Store.Call("add", map[string]interface{}{"id": "00-03", "name": "Karam", "age": 19, "email": "kenny@planet.org", "image": blob})

            Window.Call("alert", "First record posted.")
        }(fullUrlFile)

        // 直接返回,不做任何阻塞
        return nil
    })

   db.Request.Set("onupgradeneeded", Upgrade)
}

// main函数末尾添加阻塞逻辑,避免程序提前退出
func main() {
    // 你的原有初始化逻辑
    // ...
    
    // 永久阻塞,保持WASM进程运行
    select {}
}

内容的提问来源于stack exchange,提问作者Hasan A Yousef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:36:03