将 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
概念上与标准 onload
或 DomContentLoaded
事件没有区别
备注:
您不限于 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/
我有一个 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
概念上与标准 onload
或 DomContentLoaded
事件没有区别
备注:
您不限于 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/