Golang中如何将js.Value作为参数传递给js.Global().Get
Golang中如何将js.Value作为参数传递给js.Global().Get
尝试使用 Go WebAssembly 访问浏览器 IndexedDB,通过以下代码我能够创建 indexedDB,但在尝试使用 js.Global().Get(dbx) 访问它,甚至尝试访问 this.result 时遇到了错误。
//go:build js && wasm
package main
import (
"fmt"
"syscall/js"
)
var dbOk, dbErr js.Func
var db 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()
/* 这里我遇到了错误 */
dbx := this.result
fmt.Println("this is: ", dbx)
/**********************/
js.Global().Call("alert", "ok.")
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)
/* 这行代码是错误的,无法访问 `db` */
js.Global().Get(dbx).Call("transaction", "readwrite").Call("objectStore", "employee").Call("add", `{ id: "00-01", name: "Karam", age: 19, email: "kenny@planet.org" }`)
c := make(chan int)
<-c
}
我遇到的错误是:
# command-line-arguments
./wasm.go:21:14: this.result undefined (type js.Value has no field or method result)
./wasm.go:41:17: cannot use dbx (type js.Value) as type string in argument to js.Global().Get
为了将其与 JavaScript 对应起来,我希望这段 go 代码:
dbOk = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer dbOk.Release()
dbx := this.result
fmt.Println("this is: ", dbx)
js.Global().Call("alert", "ok.")
return nil
})
db.Set("onsuccess", dbOk)
等同于这段 JavaScript 代码:
var dbx
request.onsuccess = function(event) {
dbx = request.result;
console.log("success: "+ dbx);
};
而这段 go 代码:
js.Global().Get(dbx).Call("transaction", "readwrite").Call("objectStore", "employee").Call("add", `{ id: "00-03", name: "Karam", age: 19, email: "kenny@planet.org" }`)
用于替换这段 JavaScript 代码:
dbx.transaction(["employee"], "readwrite")
.objectStore("employee")
.add({ id: "00-03", name: "Karam", age: 19, email: "kenny@planet.org" });
更多关于Golang中如何将js.Value作为参数传递给js.Global().Get的实战教程也可以访问 https://www.itying.com/category-94-b0.html
谢谢,效果完美。
更多关于Golang中如何将js.Value作为参数传递给js.Global().Get的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
免责声明:我对 syscall/js 毫无经验,但我想我看到了问题所在:
在 Go 端你不能使用 this.result,因为 this 只是一个 js.Value,而 js.Value 类型(在 Go 中)要么没有 result 字段,要么即使有,也是未导出的(因为它是小写的),所以你无法访问它。
要访问 JavaScript 对象的属性,例如 this 的 result 属性,请使用 js.Value.Get:
this.Get("result")
在Go WebAssembly中,js.Value类型没有直接的字段访问方式。你需要使用Get()方法来访问JavaScript对象的属性。对于this.result,正确的访问方式是this.Get("result")。
以下是修正后的代码:
//go:build js && wasm
package main
import (
"fmt"
"syscall/js"
)
var dbOk, dbErr js.Func
var db 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()
// 正确访问result属性
dbx := this.Get("result")
fmt.Println("this is: ", dbx)
// 使用dbx进行后续操作
dbx.Call("transaction", "readwrite").
Call("objectStore", "employee").
Call("add", js.ValueOf(map[string]interface{}{
"id": "00-01",
"name": "Karam",
"age": 19,
"email": "kenny@planet.org",
}))
js.Global().Call("alert", "ok.")
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.Global().Get()需要字符串参数,而不是js.Value。你应该直接使用dbx.Call()来调用方法:
// 错误的方式
js.Global().Get(dbx).Call("transaction", "readwrite") // dbx是js.Value,不是字符串
// 正确的方式
dbx.Call("transaction", "readwrite") // 直接在js.Value上调用方法
如果你需要在回调函数外部访问数据库对象,可以使用闭包或全局变量:
//go:build js && wasm
package main
import (
"fmt"
"syscall/js"
)
var (
dbOk, dbErr js.Func
db js.Value
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()
dbx = this.Get("result")
fmt.Println("Database opened: ", dbx)
// 立即执行数据库操作
addEmployee()
js.Global().Call("alert", "Database opened successfully.")
return nil
})
db.Set("onsuccess", dbOk)
dbErr = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer dbErr.Release()
js.Global().Call("alert", "Failed to open database.")
return nil
})
db.Set("onerror", dbErr)
// 设置onupgradeneeded回调来创建对象存储
dbUpgrade := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
dbx := this.Get("result")
// 创建对象存储
if !dbx.Get("objectStoreNames").Call("contains", "employee").Bool() {
dbx.Call("createObjectStore", "employee", map[string]interface{}{
"keyPath": "id",
})
}
return nil
})
db.Set("onupgradeneeded", dbUpgrade)
defer dbUpgrade.Release()
c := make(chan int)
<-c
}
func addEmployee() {
if !dbx.IsUndefined() && !dbx.IsNull() {
tx := dbx.Call("transaction", "employee", "readwrite")
store := tx.Call("objectStore", "employee")
employee := map[string]interface{}{
"id": "00-01",
"name": "Karam",
"age": 19,
"email": "kenny@planet.org",
}
request := store.Call("add", js.ValueOf(employee))
// 设置添加操作的回调
request.Set("onsuccess", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
js.Global().Call("alert", "Employee added successfully.")
return nil
}))
request.Set("onerror", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
js.Global().Call("alert", "Failed to add employee.")
return nil
}))
}
}
关键点:
- 使用
this.Get("result")而不是this.result来访问JavaScript对象的属性 - 直接在
js.Value上使用Call()方法,而不是通过js.Global().Get() - 使用
js.ValueOf()将Go值转换为JavaScript值 - 确保在数据库成功打开后再执行操作


