将 WebAssembly 模块包装到 Web 组件中时的异步问题

Async issues when wrapping a WebAssembly module into a Web Component

我有一个 WebAssembly 模块,可以在 HTML5 WebGL canvas 上渲染一些东西。一切正常。但是,我想将所有内容包装在一个 Web 组件中以简化该模块的使用。

WebAssembly 模块非常大,因此需要几秒钟的时间来下载。一旦 WebAssembly 模块下载完成,就会调用一个 JavaScript 回调函数。

当模块下载正在进行时,向用户提供一些视觉反馈,我正在下载模块时向 canvas 绘制动画。该动画在回调函数中停止,模块在那里实例化。

从概念上讲,我正在努力将 JavaScript 回调函数与代表 Web 组件的 class 结合起来。这是我目前所拥有的:

// Code that starts downloading the WebAssembly module (asynchronous)
...

var downloadAnimation;

// The class that represents the custom Web Component
class MyWebComponent extends HTMLCanvasElement {
  constructor() {
    super();
    // Initialization
    ...
  }

  connectedCallback() {
    // Start the animation indicating to the user that a download is in progress
    downloadAnimation = new DownloadAnimation(this);
    downloadAnimation.start();
  }

  // custom functions and properties enabling the usage of the WebAssembly module
  ...
}

// Register the custom Web Component so that instances of it can be created.
// If this were to be done in the onModuleReady callback function there would
// not be an animation that runs while the download is in progress.
if(!customElements.get("MyWebComponent")) {
  customElements.define("MyWebComponent", MyWebComponent, { extends: "canvas" });
}

// Called once the WebAssembly module is downloaded, i.e. when we're ready to instantiate it
function onModuleReady() {
  // First, the download animation is stopped
  downloadAnimation.stop();

  // Next, I could instantiate the WebAssembly module as shown below.
  // But how do I connect that instance with the instance of the Web Component
  // that is created via HTML?
  let myWebAssemblyInstance = new Module.MyCustomClass();
}

为了能够 运行 下载动画,必须在下载 WebAssembly 模块之前创建 Web 组件。因此,我不能简单地在onModuleReady回调函数中执行customElements.define。那样就来不及开始动画了。

下载模块后,我就可以开始创建它的实例了。但我不知道如何将此类实例与通过 HTML 创建的 Web 组件实例连接起来。因为我在代表 Web 组件的 class 之外,所以我不知道如何访问它。

有没有办法访问代表这些实例的 class 之外的 Web 组件实例,例如来自 onModuleReady?

或者,更一般地说,有人看到更好的方法来处理这个问题吗?

让您的组件监听(在 root 级别)事件。

onModuleReady 然后 调度 事件,它会冒泡。

您可能需要自定义事件:https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent

注意你需要 composed: true 事件到 'escape' shadowRoots

概念上与标准 onloadDomContentLoaded 事件没有区别

备注:

  • 您不限于 CustomEvent details 负载中的 DataTypes
    可以添加函数引用
    所以 Receiver 可以执行方法 in/from 元素 dispatched Event

  • 事件处理同步

  • 要深入了解事件处理,请参阅:事件循环到底是什么
    https://www.youtube.com/watch?v=8aGhZQkoFbQ


另见:https://pm.dartus.fr/blog/a-complete-guide-on-shadow-dom-and-event-propagation/