我将一些 WASM 代码(从 Go 代码编译而来)集成到 Angular 中以使用一些功能。目前,这只在一个地方完成,因此不会在整个应用程序中共享。我刚刚使用了 WASM 和 Go 的“标准”程序:
let go = new Go();
WebAssembly.instantiateStreaming(fetch('mywasm.wasm'), go.importObject).then((res) => {
go.run(res.instance);
myCoolWasmFunction();
});
但是,我想在应用程序的多个部分执行 WASM,因此尝试将其移动到一个服务中。在 go.run(...)
之后,我能够使用 RxJS 主题并在该函数中收听“执行请求”,但我无法向应用程序的其他部分返回任何内容。
基本上,我正在寻找一种干净且可用的方法来执行 Angular 应用程序中 wasm 公开的不同功能。我是否应该将 wasm 内容放入 index.html
并创建一个只调用那些“全局可用”函数的服务?仅使用 .d.ts
文件,我如何启用 Angular 来识别它们?
最佳答案
我在 this Github Repo 的帮助下解决了这个问题.它就像在服务内部创建一个公共(public)变量一样简单,并且在加载 WASM 时,将导出的 WASM 函数设置为该变量,以便可以从服务外部调用它们。对于以下示例,我添加了一个小的 typescript 接口(interface)以使其与类型安全一起使用:
因此,在 WASM 服务中可能如下所示:
private Suite: WasmSuite; // Here the exported functions are stored after wasm was initiated
/*
WasmSuite is defined like this:
type MyFunctionInterface = (input: string) => string;
interface WasmSuite {
myFunction: MyFunctionInterface;
}
*/
// This is just to let components know when WASM is ready
public ready: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor() {
// Init wasm, then update the ready state
this.init().then(_ => {
this.ready.next(true);
});
}
private async init() {
let go = new Go();
return WebAssembly.instantiateStreaming(
fetch('assets/main.wasm'),
go.importObject
).then((res) => {
go.run(res.instance);
// Set the Suite to an object containing the functions. The casting of the function is somewhat optional, but I think it's good practice.
this.Suite = {
myFunction: my_exported_func as MyFunctionInterface,
// "my_exported_func" is what I exported in Go via js.Global().Set("my_exported_func", js.FuncOf(myGoFunc))
};
});
}
public callMyFunction(input: string) {
// I like to publish methods to components instead of the suite object, so this is just an "interface" between callers and WASM.
return this.Suite.myFunction(input);
}
关于javascript - 如何正确地将 WASM 集成到 Angular 服务中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65384119/