🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 注意事项 要支持 wasm ,需要对中间件继续进行配置,否则无法识别 wasm apache ``` AddType application/wasm wasm ``` nginx ``` // 在 nginx.conf 的http段中添加以下行: types { application/wasm wasm; } ``` ## 语法 ``` //js Uint8Array 与go 数组转换 func CopyBytesToGo(dst []byte, src Value) int func CopyBytesToJS(dst Value, src []byte) int func ValueOf(x interface{}) Value type Value func Global() Value // 返回 js的全局对象,通常是 "window" func Null() Value func Undefined() Value func ValueOf(x interface{}) Value func (v Value) Bool() bool func (v Value) Call(m string, args ...interface{}) Value // 调用 Value 中的函数,并传入参数 func (v Value) Delete(p string) func (v Value) Equal(w Value) bool func (v Value) Float() float64 func (v Value) Get(p string) Value // 获取 value 的元素或方法,还可以通过id 的值,直接获取对应的DOM func (v Value) Index(i int) Value func (v Value) InstanceOf(t Value) bool func (v Value) Int() int func (v Value) Invoke(args ...interface{}) Value //调用Value 函数,并传参 func (v Value) IsNaN() bool func (v Value) IsNull() bool func (v Value) IsUndefined() bool func (v Value) JSValue() Value func (v Value) Length() int func (v Value) New(args ...interface{}) Value // new 一个对象 func (v Value) Set(p string, x interface{}) // 设置属性,或添加函数 func (v Value) SetIndex(i int, x interface{}) func (v Value) String() string func (v Value) Truthy() bool func (v Value) Type() Type ``` ValueOf 的映射关系 ``` | Go | JavaScript | | ---------------------- | ---------------------- | | js.Value | [its value] | | js.Func | function | | nil | null | | bool | boolean | | integers and floats | number | | string | string | | []interface{} | new array | | map[string]interface{} | new object | ``` ## 快速入门 在有golang 的环境中查找 wasm_exec.js 文件,并拷贝到web 目录下 ``` cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" . ``` 编写go代码 <details> <summary>main.go</summary> ``` package main import ( "fmt" "syscall/js" ) var sum=0 func sayHello(this js.Value, args []js.Value) interface{}{ sum++ fmt.Printf("sum: %+v\n", sum) return nil } func main() { // 注册到window中 js.Global().Set("sayHello",js.FuncOf(sayHello)) // 防止 go 退出,不然会报错,Go program has already exited c:=make(chan struct{},1) <-c } ``` </details> <br/> 编译 ``` set GOOS=js set GOARCH=wasm go build -o main.wasm main.go ``` <details> <summary>index.html</summary> ``` <!DOCTYPE html> <html lang="zh-cmn-Hans"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Title</title> <script src="wasm_exec.js"></script> </head> <body> <script> const go=new Go(); WebAssembly.instantiateStreaming(fetch("main.wasm"),go.importObject).then(async (result)=>{ await go.run(result.instance) }) window.onload=function (){ sayHello(); } </script> </body> </html> ``` </details> <br/> 在浏览器中访问,即可在控制台查看输出 ### 更好的 js 导入 wasm ``` <script> // This is a polyfill for FireFox and Safari if (!WebAssembly.instantiateStreaming) { WebAssembly.instantiateStreaming = async (resp, importObject) => { const source = await (await resp).arrayBuffer() return await WebAssembly.instantiate(source, importObject) } } // Promise to load the wasm file function loadWasm(path) { const go = new Go() return new Promise((resolve, reject) => { WebAssembly.instantiateStreaming(fetch(path), go.importObject) .then(result => { go.run(result.instance) resolve(result.instance) }) .catch(error => { reject(error) }) }) } // Load the wasm file loadWasm("main.wasm").then(wasm => { console.log("main.wasm is loaded 👋") }).catch(error => { console.log("ouch", error) }) </script> ```