Estoy usando emscripten para generar un archivo a.wasm.js que contiene funciones en C++ para el cifrado. Las funciones webassembly aceptan y devuelven C-strings que contienen datos JSON. Quiero envolver estas funciones asm.js para un uso más conveniente en mi aplicación cliente. Desafortunadamente, hacerlo directamente dentro de body.onload no parece funcionar, así que estoy usando el siguiente truco:
<script> !function(e, t){ console.log("Loading client..."); var n = "a.wasm.js"; if(!e.WebAssembly){ n = "a.js" } console.log("Script set to " + n); var o = t.createElement("script"); o.async = true, o.type = "text/javascript", o.src = n, o.onerror = function(t) { console.error("Script Error"), console.error(t), setTimeout(function() { e.location.reload(!0) }, 3e3) }; var r = t.getElementsByTagName("script")[0]; r.parentNode.insertBefore(o, r) }(window, document); </script> <script> setTimeout(function(){ let _generateKeyPair = Module.cwrap('generateKeyPair', 'string', null); window.generateKeyPair = function() { return JSON.parse(_generateKeyPair()); } }, 1000) </script>Por supuesto, el problema aquí es que no puedo usar "generateKeyPair" hasta 1 segundo después de que se carga la aplicación.
¿Hay alguna devolución de llamada a la que pueda conectarme para saber que el objeto Módulo asm.js se ha cargado completamente y puedo comenzar a usar las funciones definidas dentro de él?
Un enfoque es definir y esperar una promesa Module.ready . Esto se inyecta durante la compilación de Emscripten usando el --post-js . ( ver ejemplos completos )
<script src="wasm-module.js"></script> <script> Module.ready .then(api => console.log( api.sayHello() )) .catch(e => console.error('💩', e)) </script> $ emcc \ -O0 `# leave uncompressed for example` \ -s WASM=1 \ -s EXPORTED_FUNCTIONS="['_hello']" \ -s EXTRA_EXPORTED_RUNTIME_METHODS="['cwrap']" \ -o wasm-module.js \ --post-js module-post.js \ hello.c // hello.c char *hello() { return "Hello there. Welcome to WebAssembly."; } // module-post.js // Module.ready resolves when WASM instantiates. (ready is now a property and not function via @surma fork) Module.ready = new Promise(function(resolve, reject) { addOnPreMain(function() { var api = { sayHello: Module.cwrap('hello', 'string', []) }; resolve(api); }); // Propagate error to Module.ready.catch() // WARNING: this is a hack based Emscripten's current abort() implementation // and could break in the future. // Rewrite existing abort(what) function to reject Promise before it executes. var origAbort = this.abort; this.abort = function(what) { reject(Error(what)); origAbort.call(this, what); } });