什么是 WebAssembly
WebAssembly(以下简称 wasm)是一种新的编码方式,可以在现代的网络浏览器中运行。啥意思,就是除了 JavaScript(以下简称 js),还有一种语言可以在浏览器里面运行了!
对于网络平台而言,WebAssembly 具有巨大的意义——它提供了一条途径,以使得以各种语言编写的代码都可以以接近原生的速度在 Web 中运行。在这种情况下,以前无法以此方式运行的客户端软件都将可以运行在 Web 中。
编译支持 wasm 的 go
golang 的 release 版本(1.10)还不支持 wasm,但是在 github.com/golang/go 的 master 分支中已经包含 wasm 了,所以我们需要自己编译一个 go。
git clone https://github.com/golang/go /path/go
cd /path/go/src
./make.bash
/path/go/bin/
目录下会生成编译后的 go:/path/go/bin/go
设置GOROOT
为/path/go/
创建自己的 wasm 程序
参见项目:https://github.com/chyroc/golang-wasm-example
index.html
index.html
引入了wasm_exec.js
(这个是从/path/go/misc/wasm/wasm_exec.js
复制来过的)和加载 wasm 的 js(这个参见参见文档),总之这样我们的 wasm 就已经加载到我们的网页了
最后有一个显示数字的 span 块,和两个+和-的 button,我们待会写的 wasm 代码就是操作这个 span 块的
<html>
<head>
<title>加1减1</title>
<script src="wasm_exec.js"></script>
<script type="text/javascript">
function fetchAndInstantiate(url, importObject) {
return fetch(url).then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results =>
results.instance
);
}
var go = new Go();
var mod = fetchAndInstantiate("./example.wasm", go.importObject);
window.onload = function () {
mod.then(function (instance) {
go.run(instance);
});
};
</script>
</head>
<body>
<br>
<div>加1减1</div>
<br>
<button id="minus" type="button" disabled=true>-</button>
<span id="number">0</span>
<button id="plus" type="button" disabled=true>+</button>
</body>
</html>
wasm.go
第一行有 build tag:// +build js,wasm
表示GOARCH
是wasm
,GOOS
是js
然后syscall/js
包提供了操作网页的接口:
js.Global.Get("document").Call("getElementById", "number")
这几行获取到刚刚index.html
中最后一个按钮和 span 块
全局变量number
是我们最后操作的数字
然后对+和-按钮添加事件监听,监听到按了+,就将number
加 1;监听到按了-,就将number
减 1;并渲染 span 块。
plus.Set("disabled", false)
这两句会在页面 wasm 加载后将+和-按钮 disable 状态去掉,变成可点击状态
最后使用select{}
阻塞 go 程序不退出
// +build js,wasm
package main
import (
"syscall/js"
"strconv"
)
func main() {
var numberDoc = js.Global.Get("document").Call("getElementById", "number")
var plus = js.Global.Get("document").Call("getElementById", "plus")
var minus = js.Global.Get("document").Call("getElementById", "minus")
var number int
plus.Call("addEventListener", "click", js.NewCallback(func(args []js.Value) {
println("press +")
number++
numberDoc.Set("innerHTML", strconv.Itoa(number))
}))
minus.Call("addEventListener", "click", js.NewCallback(func(args []js.Value) {
number--
numberDoc.Set("innerHTML", strconv.Itoa(number))
println("press -")
}))
plus.Set("disabled", false)
minus.Set("disabled", false)
select {}
}
程序效果请访问:https://chyroc.cn/golang-wasm-example/ 体验