同步实例化
此示例展示了如何同步初始化 WebAssembly 模块,而不是 异步 初始化。在大多数情况下,默认的异步初始化模块的方式就足够了。但是,在某些情况下,您可能希望按需延迟加载模块,并同步编译和实例化它。请注意,这仅在主线程之外有效,并且由于大型模块的编译和实例化可能很昂贵,因此您应该仅在您的用例中绝对需要时才使用此方法。否则,您应该使用 默认方法。
对于这种部署策略,不需要 Webpack 等打包器。有关部署的更多信息,请参阅 专用文档。
首先,让我们看一下我们的小型库
# #![allow(unused_variables)] #fn main() { use wasm_bindgen::prelude::*; #[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(value: &str); } #[wasm_bindgen] pub fn greet(name: &str) { log(&format!("Hello, {}!", name)); } #}
接下来,让我们看一下 `index.html`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
/**
* First off we spawn a Web Worker. That's where our lib will be used. Note that
* we set the `type` to `module` to enable support for ES modules.
*/
const worker = new Worker("/worker.js", { type: "module" });
/**
* Here we listen for messages from the worker.
*/
worker.onmessage = ({ data }) => {
const { type } = data;
switch (type) {
case "FETCH_WASM": {
/**
* The worker wants to fetch the bytes for the module and for that we can use the `fetch` API.
* Then we convert the response into an `ArrayBuffer` and transfer the bytes back to the worker.
*
* @see https://mdn.org.cn/en-US/docs/Web/API/Fetch_API
* @see https://mdn.org.cn/en-US/docs/Glossary/Transferable_objects
*/
fetch("/pkg/synchronous_instantiation_bg.wasm")
.then((response) => response.arrayBuffer())
.then((bytes) => {
worker.postMessage(bytes, [bytes]);
});
break;
}
default: {
break;
}
}
};
</script>
</body>
</html>
否则,其余的魔法发生在 `worker.js` 中
import * as wasm from "./pkg/synchronous_instantiation.js";
self.onmessage = ({ data: bytes }) => {
/**
* When we receive the bytes as an `ArrayBuffer` we can use that to
* synchronously initialize the module as opposed to asynchronously
* via the default export. The synchronous method internally uses
* `new WebAssembly.Module()` and `new WebAssembly.Instance()`.
*/
wasm.initSync(bytes);
/**
* Once initialized we can call our exported `greet()` functions.
*/
wasm.greet("Dominic");
};
/**
* Once the Web Worker was spawned we ask the main thread to fetch the bytes
* for the WebAssembly module. Once fetched it will send the bytes back via
* a `postMessage` (see above).
*/
self.postMessage({ type: "FETCH_WASM" });
就是这样!请务必阅读有关 部署选项 的内容,以了解在没有打包器的情况下部署的含义。