如何将Apps Metadata传入类的静态方法?
问题结论
需要引入metadata的场景完全可以使用静态方法实现需求,两次报错均为代码使用方式错误导致。
错误原因说明
第一个报错:ReferenceError: metadata is not defined
静态方法logInfo内部直接访问全局作用域下的metadata变量,要么metadata未在全局暴露,要么Logger类加载时metadata还未完成初始化,导致无法读取变量。
第二个报错:ReferenceError: Cannot access 'Logger' before initialization
你编写的实例化Logger的代码,执行顺序排在了Logger类的定义代码之前,JS执行时找不到已经初始化完成的Logger类,因此抛出错误。
修复方案
方案1:坚持使用静态方法(推荐,符合你最初的设计目的)
子方案1.1 静态方法新增参数传递token
修改Logger类代码,删除对全局metadata的依赖:
class Logger { constructor(settings) { this.settings = settings; } // 新增token入参 static async logInfo(data = {}, token) { console.log('Hello!') const url = 'exampleUrl' // 补充await,否则fetch未完成就调用json会报错 const response = await fetch(url, { method: 'POST', headers: { "Token": token, "Content-Type": "application/json" }, body: JSON.stringify(data) }); return response.json(); } }
调用时传入metadata中的token即可:
Logger.logInfo(bugInfo, metadata.settings.token) // 补充箭头函数包裹,避免collapse方法提前执行 .then(() => collapse.collapse('toggle'))
子方案1.2 预初始化静态配置
如果不想每次调用都传token,可以给静态类增加初始化方法:
class Logger { // 静态配置存储属性 static settings = null; // 静态初始化方法,项目启动、metadata就绪后调用一次即可 static init(settings) { this.settings = settings; } constructor(settings) { this.settings = settings; } static async logInfo(data = {}) { console.log('Hello!') const url = 'exampleUrl' const response = await fetch(url, { method: 'POST', headers: { "Token": this.settings.token, "Content-Type": "application/json" }, body: JSON.stringify(data) }); return response.json(); } }
在业务代码执行前,先执行初始化(必须放在Logger类定义之后):
Logger.init(metadata.settings);
原有调用方式无需修改即可正常运行。
方案2:改用实例方法(如果你后续需要扩展Logger的实例能力)
把logInfo改为实例方法,去掉static修饰符:
class Logger { constructor(settings) { this.settings = settings; } // 去掉static,改为实例方法 async logInfo(data = {}) { console.log('Hello!') const url = 'exampleUrl' const response = await fetch(url, { method: 'POST', headers: { "Token": this.settings.token, "Content-Type": "application/json" }, body: JSON.stringify(data) }); return response.json(); } }
实例化代码必须放在Logger类定义之后执行:
const logger = new Logger(metadata.settings); // 调用方式改为实例调用 logger.logInfo(bugInfo).then(() => collapse.collapse('toggle'))
额外注意
你原有代码存在两个隐藏问题需要同步修复:
fetch是异步方法,原代码没有加await修饰,会导致response还未返回就调用json()方法抛出异常then中直接写collapse.collapse('toggle')会在调用logInfo时立刻执行该逻辑,不会等待异步请求结束,需要用箭头函数包裹成回调
内容的提问来源于stack exchange,提问作者cbln
相关产品推荐
相关产品推荐

