Как правильно интегрировать WASM в сервис Angular

Я интегрировал некоторый код WASM (скомпилированный из кода Go) в Angular, чтобы использовать некоторые функции. На данный момент это делается только в одном месте и поэтому не используется во всем приложении. Я просто использовал «стандартную» процедуру для WASM и Go:

let go = new Go();

WebAssembly.instantiateStreaming(fetch('mywasm.wasm'), go.importObject).then((res) => {
  go.run(res.instance);

  myCoolWasmFunction();
});

Однако я хотел бы выполнить WASM в нескольких частях приложения и, таким образом, попытался перенести это в службу. Я смог использовать тему RxJS и прослушивать «запросы на выполнение» в этой функции после go.run(...), но я не мог ничего вернуть в другие части приложения.

По сути, я ищу чистый и удобный способ выполнения различных функций, предоставляемых wasm в приложении Angular. Должен ли я просто поместить материал wasm в index.html и создать сервис, который просто вызывает эти «глобально доступные» функции? Как я могу позволить angular распознавать их только с помощью файла .d.ts?

Я не уверен на 100%, так как я не очень часто использовал Go-WASM (хотя я использовал GopherJS)... но я не думаю, что это будет работать так, как вы ожидаете. Я думаю, вам нужна единая точка входа в ваше приложение Go. В противном случае вы получите несколько запущенных экземпляров среды выполнения Go.

Jonathan Hall 20.12.2020 20:51
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Раскрытие чувствительных данных
Раскрытие чувствительных данных
Все внешние компоненты, рассмотренные здесь до сих пор, взаимодействуют с клиентской стороной. Однако, если они подвергаются атаке, они не...
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Руководство ChatGPT по продаже мини JS-файлов
Руководство ChatGPT по продаже мини JS-файлов
JS-файл - это файл, содержащий код JavaScript. JavaScript - это язык программирования, который в основном используется для добавления интерактивности...
3
1
3 732
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я решил это с помощью этого Github Repo. Это так же просто, как создать общедоступную переменную внутри службы и при загрузке WASM установить экспортированные функции WASM в эту переменную, чтобы их можно было вызывать извне службы. Для следующего примера я добавил небольшой интерфейс машинописного текста, чтобы он работал с безопасностью типов:

Итак, в сервисе 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);
}

Как вы импортировали модули wasm? Я ненавижу, когда люди просто вставляют код, но забывают об импорте.... :-(

Juan Vilar 03.12.2021 10:34

Извините, что вернулся после ГОД этой публикации, но у меня возникли проблемы с тем, как импортировать файл wasm, который я только что скомпилировал, и использовать его.

Juan Vilar 03.12.2021 10:35

Импорт есть в коде: return WebAssembly.instantiateStreaming(fetch('assets/main.wasm'), go.importObject). Прочтите эту статью, чтобы узнать больше: golangbot.com/webassembly-using-go

Janis Jansen 03.12.2021 11:27

Другие вопросы по теме