JS模块导入全局变量后recoveryDevicesInDB函数重复执行问题
问题原因
你遇到的重复执行问题是因为main.js和functions.mjs形成了循环模块依赖:main.js导入functions.mjs,同时functions.mjs又导入main.js的DEVICES_GLOBAL,这种循环引用会导致模块代码被重复执行,进而触发两次recoveryDevicesInDB()调用。
解决方案
下面两种方法都能解决问题,同时满足你在functions.mjs中访问全局变量的需求:
方法1:拆分全局变量到独立模块(推荐)
把全局状态单独抽成一个独立模块,彻底避免循环依赖:
- 创建
globalState.mjs文件:
export const DEVICES_GLOBAL = {};
- 修改
main.js:
// 导入全局状态和functions方法 import { DEVICES_GLOBAL } from './globalState.mjs'; import { recoveryDevicesInDB } from './functions.mjs'; // 调用方法 recoveryDevicesInDB();
- 修改
functions.mjs:
// 导入独立模块的全局变量,不再导入main.js import { DEVICES_GLOBAL } from './globalState.mjs'; export function openDatabase() { // 你的IndexedDB打开逻辑 } export function recoveryDevicesInDB() { // 读取数据并存入DEVICES_GLOBAL,然后渲染表格的逻辑 }
方法2:挂载到window全局对象
如果不想新增模块,直接把DEVICES_GLOBAL挂载到浏览器的window对象上:
- 修改
main.js:
import { recoveryDevicesInDB } from './functions.mjs'; // 直接挂载到window,不需要导出 window.DEVICES_GLOBAL = {}; // 调用方法 recoveryDevicesInDB();
- 修改
functions.mjs:
export function openDatabase() { // 你的IndexedDB打开逻辑 } export function recoveryDevicesInDB() { // 直接通过window访问全局变量 const devicesGlobal = window.DEVICES_GLOBAL; // 读取数据并存入devicesGlobal,然后渲染表格的逻辑 }
注意事项
- 循环模块依赖在ES模块中虽语法允许,但极易触发意外的执行逻辑重复,尽量通过拆分模块避免。
- 使用window全局对象时要注意命名冲突,建议给变量加独特前缀(比如
QR_DEVICES_GLOBAL)。
内容的提问来源于stack exchange,提问作者cisco horux
相关产品推荐
相关产品推荐

