Go WebAssembly操作IndexedDB时js.Value相关调用报错如何解决
解决方案
报错根因说明
- 第一个报错
this.result undefined (type js.Value has no field or method result):
Go的syscall/js包无法直接通过.属性名的方式读取JS对象属性,必须调用js.Value的Get()方法传入属性名获取值。 - 第二个报错
cannot use dbx (type js.Value) as type string in argument to js.Global().Get:js.Global().Get()仅接收字符串类型的全局变量名作为入参,而dbx本身已经是数据库实例的js.Value对象,无需再从全局作用域查询,可直接调用其方法。 - 隐藏问题:IndexedDB的
open是异步操作,你在main函数中直接执行数据库读写时,onsuccess回调还未触发,dbx尚未完成初始化,会拿到空值报错;同时add方法不能直接传入JSON字符串,需要转成JS对象。
调整后的完整代码
//go:build js && wasm package main import ( "fmt" "syscall/js" ) var dbOk, dbErr js.Func var db js.Value var dbx js.Value // 全局存储数据库实例 func main() { fmt.Println("Hello WASM") db = js.Global().Get("indexedDB").Call("open", "Database", 1) dbOk = js.FuncOf(func(this js.Value, args []js.Value) interface{} { defer dbOk.Release() // 修复1:通过Get方法获取result属性 dbx = this.Get("result") fmt.Println("this is: ", dbx) js.Global().Call("alert", "ok.") // 修复2:异步操作放在onsuccess回调中执行,保证dbx已初始化 // 构造要插入的JS对象 insertData := js.ValueOf(map[string]interface{}{ "id": "00-03", "name": "Karam", "age": 19, "email": "kenny@planet.org", }) // 修复3:直接用dbx调用方法,transaction第一个参数传数组 dbx.Call("transaction", js.ValueOf([]interface{}{"employee"}), "readwrite"). Call("objectStore", "employee"). Call("add", insertData) return nil }) db.Set("onsuccess", dbOk) dbErr = js.FuncOf(func(this js.Value, args []js.Value) interface{} { defer dbErr.Release() js.Global().Call("alert", "sorry.") return nil }) db.Set("onerror", dbErr) c := make(chan int) <-c }
对应JS逻辑说明
调整后的代码完全匹配你给出的JS等效逻辑:
- 全局声明
dbx存储数据库实例,在onsuccess回调中通过this.Get("result")拿到实例赋值,和JS的dbx = request.result逻辑完全一致 - 直接通过
dbx.Call()调用transaction方法,传参符合JS的dbx.transaction(["employee"], "readwrite")规则,插入数据也直接构造对应JS对象传入add方法,和目标JS逻辑完全等效。
内容的提问来源于stack exchange,提问作者Hasan A Yousef
相关产品推荐
相关产品推荐

