Búsqueda de sitios web

typescript - Error al usar la función wasm en vue


Cuando quiero usar wasm en Vue, lo primero es que tengo un problema irresoluble, la función startQuorum en mi archivo wasm no se puede encontrar.

import { Go } from './wasm_exec'
import quorumWasmUrl from './lib.wasm'

export const startQuorum = async (bootstraps: Array<string>) => {
  const go = new Go()
  WebAssembly.instantiateStreaming(fetch(quorumWasmUrl), go.importObject).then(
    async (result) => {
      go.run(result.instance)
      const StartQuorum = result.instance.exports.StartQuorum as CallableFunction
      // StartQuorum is a function. but ts can not find it.
      await StartQuorum('password', bootstraps.join(','))
    }
  )
  console.log('startQuorum over')
}

Y los archivos wasm escritos en Go. La función original es así

js.Global().Set("StartQuorum", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        if qChan == nil {
            qChan = make(chan struct{}, 0)
        }
        if len(args) < 2 {
            return nil
        }
        password := args[0].String()
        bootAddrsStr := args[1].String()
        bootAddrs := strings.Split(bootAddrsStr, ",")

        handler := func() (map[string]interface{}, error) {
            ret := make(map[string]interface{})
            ok, err := StartQuorum(qChan, password, bootAddrs)
            ret["ok"] = ok
            if err != nil {
                return ret, err
            }
            return ret, nil
        }
        return Promisefy(handler)
    }))

Eso significa que la función StartQuorum en wasm existe, pero TypeScript no puede encontrarla, el navegador devuelve esto.

Uncaught (in promise) TypeError: StartQuorum is not a function
at eval (load-quorum.ts?b7b7:139:1)

El archivo wasm se carga bien, mi diagnóstico inicial es que ts no reconoce las funciones en wasm.

¿Cómo puedo resolverlo?

Respuesta #1

Eso ocurre porque no es una función exportada. Actualmente, el compilador de Golang no soporta funciones exportadas (solo la importación, mediante la instrucción de ensamblaje mágica CALLIMPORT). Digo "compilador de Golang" porque eso no es cierto si estás usando TinyGo u otro compilador.


De todos modos, usar js.Global().Set establecerá la función en js.Global(), que es window/globalThis o equivalente:

js.Global().Set("StartQuorum", ....)

Eso está creando la función StartQuorum a nivel de window/globalThis. Por lo tanto, la función debe llamarse usando: window.StartQuorum().


Entonces, esta línea:

const StartQuorum = result.instance.exports.StartQuorum as CallableFunction
// StartQuorum is a function. but ts can not find it.

await StartQuorum('password', bootstraps.join(','))

No parece tener sentido, ya que result.instance.exports.StartQuorum siempre es nulo. Tu función se encuentra en window.StartQuorum o globalThis.StartQuorum (...).

Eso no es una función exportada de WebAssembly (que estará en result.instance.exports.