Golang中如何解决js.Value转换为map[string]interface{}类型失败的问题
Golang中如何解决js.Value转换为map[string]interface{}类型失败的问题
在我的WASM代码中,我获取了一个js.Value,它是一个JavaScript对象,并且如此处所示,JavaScript对象与Go的map[string]interface{}映射。
在我的代码中,我尝试了以下方法来从返回的对象中获取数据,使用了这段将JSON转换为map[string]interface{}的代码:
ReadAll = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
// defer ReadAll.Release()
cursor := this.Get("result")
if cursor.Truthy() {
_ = cursor.Get("key")
value := cursor.Get("value")
// Decode incoming json
jsonMap := make(map[string]interface{})
json.Unmarshal([]byte(value), &jsonMap)
// var content []map[string]interface{}
// json.Unmarshal([]byte(jsonMap["name"].(string)), &content)
Window.Call("alert", jsonMap)
cursor.Call("continue")
} else {
Window.Call("alert", "No more records")
}
return nil
})
但是我遇到了错误:
./cursor.go:20:25: 无法将值(类型 js.Value)转换为类型 byte
更多关于Golang中如何解决js.Value转换为map[string]interface{}类型失败的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
我通过使用 value.Get() 成功实现了,以下是新的代码:
if cursor.Truthy() {
key := cursor.Get("key")
value := cursor.Get("value")
data := fmt.Sprintf("Name for id %v is %v, Age: %v, Email: %v", key,
value.Get("name"), value.Get("age"), value.Get("email"))
// 等效的 JavaScript 代码:
// alert("Name for id " + cursor.key + " is " + cursor.value.name + ", Age: "
// + cursor.value.age + ", Email: " + cursor.value.email);
Window.Call("alert", data)
cursor.Call("continue")
} else {
Window.Call("alert", "No more records")
}
更多关于Golang中如何解决js.Value转换为map[string]interface{}类型失败的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在WASM中处理js.Value到map[string]interface{}的转换时,不能直接使用json.Unmarshal,因为js.Value不是[]byte类型。以下是正确的解决方案:
import (
"encoding/json"
"syscall/js"
)
func jsValueToMap(value js.Value) (map[string]interface{}, error) {
// 使用JSON.stringify将JavaScript对象转换为JSON字符串
jsonStr := js.Global().Get("JSON").Call("stringify", value).String()
// 将JSON字符串解析为Go的map
result := make(map[string]interface{})
err := json.Unmarshal([]byte(jsonStr), &result)
if err != nil {
return nil, err
}
return result, nil
}
// 在你的代码中使用
ReadAll = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
cursor := this.Get("result")
if cursor.Truthy() {
value := cursor.Get("value")
// 正确转换js.Value到map
jsonMap, err := jsValueToMap(value)
if err != nil {
js.Global().Call("alert", "解析错误: "+err.Error())
return nil
}
js.Global().Call("alert", js.ValueOf(jsonMap))
cursor.Call("continue")
} else {
js.Global().Call("alert", "No more records")
}
return nil
})
如果value已经是JSON字符串,可以直接解析:
ReadAll = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
cursor := this.Get("result")
if cursor.Truthy() {
value := cursor.Get("value")
// 检查value是否是字符串
if value.Type() == js.TypeString {
jsonMap := make(map[string]interface{})
err := json.Unmarshal([]byte(value.String()), &jsonMap)
if err != nil {
js.Global().Call("alert", "JSON解析错误: "+err.Error())
return nil
}
js.Global().Call("alert", js.ValueOf(jsonMap))
} else {
// 如果是JavaScript对象,使用JSON.stringify方法
jsonStr := js.Global().Get("JSON").Call("stringify", value).String()
jsonMap := make(map[string]interface{})
err := json.Unmarshal([]byte(jsonStr), &jsonMap)
if err != nil {
js.Global().Call("alert", "对象转换错误: "+err.Error())
return nil
}
js.Global().Call("alert", js.ValueOf(jsonMap))
}
cursor.Call("continue")
} else {
js.Global().Call("alert", "No more records")
}
return nil
})
对于更复杂的嵌套结构转换,可以使用递归方法:
func jsValueToGo(value js.Value) interface{} {
switch value.Type() {
case js.TypeObject:
// 检查是否为数组
if js.Global().Get("Array").Call("isArray", value).Bool() {
length := value.Length()
arr := make([]interface{}, length)
for i := 0; i < length; i++ {
arr[i] = jsValueToGo(value.Index(i))
}
return arr
}
// 处理普通对象
keys := js.Global().Get("Object").Call("keys", value)
m := make(map[string]interface{})
for i := 0; i < keys.Length(); i++ {
key := keys.Index(i).String()
m[key] = jsValueToGo(value.Get(key))
}
return m
case js.TypeString:
return value.String()
case js.TypeNumber:
return value.Float()
case js.TypeBoolean:
return value.Bool()
case js.TypeNull, js.TypeUndefined:
return nil
default:
return value.String()
}
}
// 使用示例
ReadAll = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
cursor := this.Get("result")
if cursor.Truthy() {
value := cursor.Get("value")
goMap := jsValueToGo(value).(map[string]interface{})
// 现在goMap可以直接在Go代码中使用
js.Global().Call("alert", js.ValueOf(goMap))
cursor.Call("continue")
}
return nil
})

