React应用中如何让原生JS文件调用WebAssembly函数?
解决方法
方案1:将WASM实例挂载到全局对象
在WASM初始化完成后,把实例挂载到浏览器的window全局对象上,原生JS文件就能直接访问到它。
// WASM初始化入口文件 import init from './wasm/pkg'; init().then((wasm) => { // 挂载到全局 window.wasmInstance = wasm; // 渲染React应用 ReactDOM.render(<App />, document.getElementById('root')); });
定时器文件中直接调用:
// 全局单例定时器文件 class TimerService { constructor() { this.timer = null; } start() { this.timer = setInterval(() => { // 先判断实例是否已挂载,避免报错 if (window.wasmInstance) { const calculationResult = window.wasmInstance.complexCompute(); // 处理计算结果 } }, 1000); } } export default new TimerService();
方案2:给定时器模块提供初始化入口
让定时器模块暴露一个init方法,在WASM加载完成后传入实例,模块内部保存这个引用。
// 全局单例定时器文件 let wasmInstance = null; class TimerService { constructor() { this.timer = null; } // 接收WASM实例并保存 init(wasm) { wasmInstance = wasm; } start() { this.timer = setInterval(() => { if (wasmInstance) { const calculationResult = wasmInstance.complexCompute(); // 处理计算结果 } }, 1000); } } export default new TimerService();
在WASM初始化时调用定时器的init方法:
// WASM初始化入口文件 import init from './wasm/pkg'; import timerService from './timerService'; init().then((wasm) => { timerService.init(wasm); ReactDOM.render(<App />, document.getElementById('root')); });
方案3:缓存WASM初始化的Promise
单独创建一个文件缓存WASM初始化的Promise,定时器模块直接通过这个Promise获取实例。
// wasmCache.js import init from './wasm/pkg'; // 缓存初始化Promise,避免重复初始化 export const wasmReady = init();
定时器文件中使用:
// 全局单例定时器文件 import { wasmReady } from './wasmCache'; class TimerService { constructor() { this.timer = null; this.wasmInstance = null; // 提前预加载WASM实例 wasmReady.then(wasm => { this.wasmInstance = wasm; }); } start() { this.timer = setInterval(async () => { // 如果实例未就绪,等待初始化完成 if (!this.wasmInstance) { this.wasmInstance = await wasmReady; } const calculationResult = this.wasmInstance.complexCompute(); // 处理计算结果 }, 1000); } } export default new TimerService();
内容的提问来源于stack exchange,提问作者Cirrocumulus
相关产品推荐
相关产品推荐

