WebAssembly:未来前端开发的必备技能

一. 前言

WebAssembly 是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如 C / C ++等语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。

二. 快速上手

1. 用go写一个hello world

package main

import (
	"fmt"
)

func main() {
   
	fmt.Println("Hello, WebAssembly!")
}

2. 将go文件编译成wasm文件

GOOS=js GOARCH=wasm go build -o static/main.wasm

3. 拷贝出wasm_exec.js

该文件为go的wasm的js支持文件

cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" static

4. html文件调用wasm文件

<script src="static/wasm_exec.js"></script>
<script>
  const go = new Go();
  WebAssembly.instantiateStreaming(fetch("static/main.wasm"), go.importObject)
    .then((result) => go.run(result.instance))
</script>

5. 验证调用

浏览器加载html文件,f12打开控制台,可以看到wasm的打印消息。

三. go与js的类型转换

1. 类型映射

| 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             |

如上为官方给出的go与js的类型映射表。

比如在go中调用js函数,参数为array,那么就可以直接将go的[]interface{}类型的变量作为参数使用。

2. 函数转换数组

syscall/js提供了两个函数:

  • CopyBytesToGo:func CopyBytesToGo(dst []byte, src Value) int
  • CopyBytesToJS:func CopyBytesToJS(dst Value, src []byte) int

两者对于go而言,类型都是[]byte,但是对于js而言,需要Uint8Array或者Uint8ClampedArray类型,否则就会报错。

那么,如何在go中生成一个Uint8Array或者Uint8ClampedArray类型的变量呢?官方的类型映射表也没有啊…那么就看下一步。

3. 其余类型

对于非官方类型映射表内的类型,和官方提供的两个数据类型转换之外的类型,可以通过一种通用的方式来生成,以上一步的Uint8Array为例:

js.Global().Get("Uint8Array").New(<length>)

实际使用案例:

// goData []byte{...}
jsData := js.Global().Get("Uint8Array").New(len(goData))
js.CopyBytesToJS(jsData, goData)

那么,比如js中的Date类型:

dateConstructor := js.Global().Get("Date")
dateConstructor.New("2020-10-01")

4. 极端情况

好吧,还有最后一个方案,如果遇到极端情况,上述方案都无法解决,那么请转换成字符串吧!让go和js用各自的方法分别处理一波,得到自己想要的结果或者给出各自想给的数据。

四. js调用go函数

此处需要在go中引入syscall/js,以实现js相关的操作。

1. 注册go函数

将go的函数注册为js的函数,由js来进行调用。

package main

import "syscall/js"

func handleCount(this js.Value, args []js.Value) interface{
   } {
   
  count := args[0].Int()
  return js.ValueOf(count + 1)
}

func main() {
   
	done := make(chan string, 0)
	js.Global().Set("HandleEvent", js.FuncOf(handleEvent))
	<-done
}

js.Func() 接受一个函数类型作为其参数,该函数的定义是固定的:

func(this Value, args []Value) interface{
   }
// this 即 JavaScript 中的 this
// args 是在 JavaScript 中调用该函数的参数列表。
// 返回值需用 js.ValueOf 映射成 JavaScript 的值

js.ValueOf返回作为js的值:

| Go                     | JavaScript             |
| ---------------------- | ---------------------- |
| js.Value               | [its value]            |
| js.Func                | function    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值