You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Go编译的WASM函数导入JS并调用?调用时遇未定义错误

问题:Go编译的WASM函数在JS中调用提示未定义,但控制台可手动调用

问题描述

将Go编译的WASM文件中的函数导入JavaScript使用时,调用函数会出现未定义错误,但WASM导入完成后,在浏览器控制台中可以手动调用该函数,需要实现JS程序内正常调用。

错误信息

Uncaught ReferenceError: add is not defined

现有代码

JavaScript代码

async function init() {
    const go = new Go();
    const result = await WebAssembly.instantiateStreaming(
      fetch("main.wasm"),
      go.importObject
    );
    go.run(result.instance);
}

add("Hello")

init();

Go代码

package main

import (
    "fmt"
    "syscall/js"
)

func add(this js.Value, inputs []js.Value) interface{} {
    var input string = inputs[0].String()

    return "you typed: " + input
}

func main() {
    fmt.Println("hi")
    js.Global().Set("add", js.FuncOf(add))

    <-make(chan bool)
}

解决方案

问题核心是调用时机错误:add("Hello")是同步执行的,而init()是异步函数,此时WASM还未加载完成,add函数还没被注册到全局对象上,因此抛出未定义错误。

只需调整调用时机,确保在WASM初始化完成后再调用add函数,有两种常见修改方式:

方式一:在init函数内部调用

async function init() {
    const go = new Go();
    const result = await WebAssembly.instantiateStreaming(
      fetch("main.wasm"),
      go.importObject
    );
    go.run(result.instance);
    
    // WASM初始化完成后再调用add
    add("Hello");
}

init();

方式二:用立即执行异步函数等待初始化完成

async function init() {
    const go = new Go();
    const result = await WebAssembly.instantiateStreaming(
      fetch("main.wasm"),
      go.importObject
    );
    go.run(result.instance);
}

// 等待init执行完毕后调用add
(async () => {
    await init();
    add("Hello");
})();

原理说明

WebAssembly.instantiateStreaming和go.run都是异步/耗时操作,只有当这些操作完成后,Go代码中的js.Global().Set("add", js.FuncOf(add))才会把add函数挂载到全局对象上。提前调用会因函数尚未存在而报错;而控制台手动调用时,WASM已经加载完成,所以能正常执行。

内容的提问来源于stack exchange,提问作者Crowbin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:01:06