根据FuncOf文档:
调用任何异步JavaScript API,这需要事件循环,如fetch(http.Client(将导致立即死锁。因此阻塞函数应该显式地启动一个新的goroutine。
所以,我写了以下代码:
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"syscall/js"
)
func (db *DataBase) init(dataSet, table string) {
var Ok, Err, Upgrade js.Func
db.Request = Window.Get("indexedDB").Call("open", dataSet, 1)
done := make(chan *bytes.Buffer)
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"
go func(fullUrlFile string) {
var blob *bytes.Buffer
r, e := http.Get(fullUrlFile)
if e != nil {
panic(e)
}
defer r.Body.Close()
buildFileName()
// Create blob
var dest []byte
blob = bytes.NewBuffer(dest)
io.Copy(blob, r.Body)
done <- blob
}(fullUrlFile)
blob := <-done
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.")
return nil
})
db.Request.Set("onupgradeneeded", Upgrade)
}
但仍然让我的应用程序退出死块!
fatal error: all goroutines are asleep - deadlock!
wasm_exec.js:51
wasm_exec.js:51 goroutine 1 [chan receive]:
wasm_exec.js:51 main.main()
wasm_exec.js:51 /home/hajsf/idb/main.go:24 +0x4
wasm_exec.js:51
wasm_exec.js:51 goroutine 6 [chan receive]:
wasm_exec.js:51 main.(*DataBase).init.func1({{}, 0x7ff8000100000011, 0x410240}, {0x40ec80, 0x1, 0x1})
wasm_exec.js:51 /home/hajsf/idb/initiate.go:57 +0xe
wasm_exec.js:51 syscall/js.handleEvent()
wasm_exec.js:51 /usr/local/go/src/syscall/js/func.go:96 +0x27
wasm_exec.js:51
wasm_exec.js:51 goroutine 7 [select]:
wasm_exec.js:51 net/http.(*Transport).RoundTrip(0x324e20, 0x492000)
wasm_exec.js:51 /usr/local/go/src/net/http/roundtrip_js.go:170 +0x8d
wasm_exec.js:51 net/http.send(0x492000, {0xbe880, 0x324e20}, {0x0, 0x0, 0x0})
wasm_exec.js:51 /usr/local/go/src/net/http/client.go:252 +0x8b
wasm_exec.js:51 net/http.(*Client).send(0x334a80, 0x492000, {0x0, 0x0, 0x0})
wasm_exec.js:51 /usr/local/go/src/net/http/client.go:176 +0x11
wasm_exec.js:51 net/http.(*Client).do(0x334a80, 0x492000)
wasm_exec.js:51 /usr/local/go/src/net/http/client.go:725 +0xb5
wasm_exec.js:51 net/http.(*Client).Do(...)
wasm_exec.js:51 /usr/local/go/src/net/http/client.go:593
wasm_exec.js:51 net/http.(*Client).Get(0x334a80, {0x7546d, 0x1f})
wasm_exec.js:51 /usr/local/go/src/net/http/client.go:480 +0xe
wasm_exec.js:51 net/http.Get(...)
wasm_exec.js:51 /usr/local/go/src/net/http/client.go:449
wasm_exec.js:51 main.(*DataBase).init.func1.1(0x4360c0, {0x7546d, 0x1f})
wasm_exec.js:51 /home/hajsf/idb/initiate.go:43 +0x4
wasm_exec.js:51 created by main.(*DataBase).init.func1
wasm_exec.js:51 /home/hajsf/idb/initiate.go:40 +0xd
wasm_exec.js:151 exit code: 2
exit @ wasm_exec.js:151
runtime.wasmExit @ wasm_exec.js:275
$runtime.wasmExit @ main.wasm:0xe065d
$runtime.exit @ main.wasm:0xe048b
$runtime.fatalthrow.func1 @ main.wasm:0x7c1a2
$runtime.systemstack @ main.wasm:0xdd8f7
$runtime.fatalthrow @ main.wasm:0x7bff8
$runtime.throw @ main.wasm:0x7ba33
$runtime.checkdead @ main.wasm:0x9bcb8
$runtime.mput @ main.wasm:0x9e0f6
$runtime.stopm @ main.wasm:0x8ae91
$runtime.findrunnable @ main.wasm:0x8d33e
$runtime.schedule @ main.wasm:0x91430
$runtime.park_m @ main.wasm:0x9247f
$runtime.mcall @ main.wasm:0xdd88c
$runtime.gopark @ main.wasm:0x81740
$runtime.selectgo @ main.wasm:0xa5c4f
$net_http.__Transport_.RoundTrip @ main.wasm:0x3f3ae3
$wasm_pc_f_loop @ main.wasm:0xe0444
$wasm_export_resume @ main.wasm:0xe0425
_resume @ wasm_exec.js:588
(anonymous) @ wasm_exec.js:599
IndexedDB (async)
syscall/js.valueCall @ wasm_exec.js:399
$syscall_js.valueCall @ main.wasm:0x14799e
$syscall_js.Value.Call @ main.wasm:0x145065
$main.__DataBase_.init @ main.wasm:0x479c61
$main.init.0 @ main.wasm:0x47d181
$runtime.doInit @ main.wasm:0xa0e3d
$runtime.main @ main.wasm:0x80948
$wasm_pc_f_loop @ main.wasm:0xe0444
$wasm_export_run @ main.wasm:0xe0417
run @ wasm_exec.js:577
init @ wasm.js:7
await in init (async)
(anonymous) @ (index):20
(anonymous) @ (index):22
wasm_exec.js:586 Uncaught (in promise) Error: Go program has already exited
at global.Go._resume (wasm_exec.js:586)
at wasm_exec.js:599
_resume @ wasm_exec.js:586
(anonymous) @ wasm_exec.js:599
Promise.then (async)
syscall/js.valueCall @ wasm_exec.js:399
$syscall_js.valueCall @ main.wasm:0x14799e
$syscall_js.Value.Call @ main.wasm:0x145065
$net_http.__Transport_.RoundTrip @ main.wasm:0x3f3943
$wasm_pc_f_loop @ main.wasm:0xe0444
$wasm_export_resume @ main.wasm:0xe0425
_resume @ wasm_exec.js:588
(anonymous) @ wasm_exec.js:599
IndexedDB (async)
syscall/js.valueCall @ wasm_exec.js:399
$syscall_js.valueCall @ main.wasm:0x14799e
$syscall_js.Value.Call @ main.wasm:0x145065
$main.__DataBase_.init @ main.wasm:0x479c61
$main.init.0 @ main.wasm:0x47d181
$runtime.doInit @ main.wasm:0xa0e3d
$runtime.main @ main.wasm:0x80948
$wasm_pc_f_loop @ main.wasm:0xe0444
$wasm_export_run @ main.wasm:0xe0417
run @ wasm_exec.js:577
init @ wasm.js:7
await in init (async)
(anonymous) @ (index):20
(anonymous) @ (index):22
wasm_exec.js:586 Uncaught Error: Go program has already exited
at global.Go._resume (wasm_exec.js:586)
at IDBOpenDBRequest.<anonymous> (wasm_exec.js:599)
有什么想法吗?
我找到了,goroutine
应该涵盖了整个功能范围,比如:
js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
[...]
someBlockingFunction()
[...]
}()
})