Веб-сборка набирает обороты и теперь поддерживается большинством современных браузеров (85%), и сейчас хорошее время для начала, если вы еще этого не сделали, начать работу с Go (Golang для поисковых систем) очень просто, и Опыт работы в этом руководстве не требуется - вы можете узнать больше о том, как работает WASM и зачем его использовать, здесь.
Для начала нам нужно сначала установить GO, вы можете проверить инструкции здесь.
После того, как мы установили Go, нам нужно создать новый каталог и в нем создать несколько исходных файлов (вы можете просто клонировать репо ):
Мы используем функцию WebAssembly.instantiateStreaming для запуска кода wasm и используем загрузчик go для запуска нашего кода wasm.
Наш main.go
файл прост: мы импортируем пакет fmt
, который имеет функции, аналогичные console.log
(для нашего использования), и по умолчанию он будет печатать на нашей консоли, и у нас есть функция с именем main
, каждый проект Go начинается с основной функции , и как только код будет загружен через wasm, эта функция запустится и напечатает «Hello, WebAssembly!» к консоли.
Теперь, когда у нас есть исходные файлы, нам нужно получить файл «wasm_exec.js», который позволит нам загрузить код wasm для go (это то, что дает нам класс Go, который мы используем в файле index.html), мы можем получить его, скопировав из корневых файлов go.
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
Теперь мы можем компилировать или кодировать из main.go
, мы компилируем в среду выполнения js (GOOS) и используем архитектуру wasm (GARCH) и выводим результат в main.wasm
file.
GOOS=js GOARCH=wasm go build -o main.wasm
Теперь у нас должен быть файл с именем main.wasm
, это файл, содержащий код веб-сборки, который мы будем запускать.
Теперь мы можем использовать любой HTTP-сервер для запуска нашего кода, я использую для него http-сервер, и мы должны увидеть нашу строку, зарегистрированную в консоли.
Именованные функции
Теперь, когда у нас есть простой рабочий код wasm, мы можем начать работу с именованными функциями, мы хотим экспортировать некоторые функции из нашего кода Go, чтобы мы могли использовать их в нашем коде javascript.
Чтобы привязать наш код Go к среде выполнения JS, Go предоставляет нам пакет syscall/js
, который мы можем импортировать и использовать для привязки функции к глобальному окну.
Как видите, наш импорт предоставляет переменную с именем js
и мы можем получить Global
, которое является окном (для браузеров), и мы можем установить функцию с помощью Set
, функция называется добавить, и мы используем js.NewCallback
, чтобы превратить нашу функцию Go в функцию javascript.
Пока не обращайте внимания на строки с done
, они используются здесь для предотвращения выхода из программы Go (путем создания канала Go и ожидания получения данных).
Давайте реализуем функцию с именем «add» в нашем коде Go, который будет принимать два числа и складывать их:
// accept any number of javascript values as arguments func add(args []js.Value) { // convert the JS values to Integers (numbers) var a = args[0].Int() var b = args[1].Int() // print the sum of the numbers fmt.Println(a + b) }
Итак, наш полный main.go
теперь выглядит так:
Теперь мы можем вызвать функцию window.add(1,2)
в нашем коде javascript.
Передача значений из Go в Javascript
Это хорошо, и это то, о чем будет рассказано в большинстве руководств, но мы хотим получить сумму, а не выводить ее на консоль.
Поскольку интерфейс js.NewCallback
не позволяет нам возвращать значения, а функции вызываются асинхронно, мы можем использовать старые добрые обратные вызовы, а позже использовать их как обещания, это функция go, которую мы будем использовать для вызова обратного вызова, она принимает массив значений js, возвращаемое значение («интерфейс {}» в основном означает любой тип) и ошибку (если таковая существует).
func execCallback(args []js.Value, value interface{}, e error) { // get the last value var last = args[len(args) - 1] // if the last argument is a function, invoke it if last.Type() == js.TypeFunction { last.Invoke(e, value) } else { println("no callback") } }
И теперь наш main.go
файл будет выглядеть так:
И когда мы перестроим его и перезагрузим веб-страницу, мы сможем вызвать add
следующим образом:
add(5, 10, (sum, error) => console.log(sum));
Мы можем превратить этот вызов в обещание, чтобы упростить нам задачу, это наш новый код js:
Очистка глобальной области видимости
Мы заканчиваем функциями, которые ограничены глобальной областью видимости, давайте вместо этого привяжем их к локальной области (любому объекту).
Я добавил функцию с именем register
, которую нам нужно будет вызвать с объектом, и назначить ее функции javascript с именем __wasm_main
, мы привяжем все другие функции к этому объекту и будем использовать их оттуда, что означает, что мы вызываем меньшее загрязнение глобальной сфера.
А теперь немного изменим наш js-код:
Что дальше?
Существует несколько загрузчиков Webpack WASM для Go, и вы можете использовать их для добавления Go в свой рабочий процесс внешнего интерфейса, а также есть очень интересный интерфейсный фреймворк, очень похожий на Vue, под названием vugu, который позволяет создавать прекрасный интерфейс. с помощью WASM и Go. Если вы не знаете го и хотите продолжить его изучение, я рекомендую совершить тур по го.