如何正确创建含异步初始化属性的JS类?代码异常排查
问题排查:Exchange实例异步初始化后平台标识异常
问题场景
因JavaScript类构造函数无法使用async/await,采用静态异步方法init实现Exchange类的异步初始化,通过以下方式创建实例:
const binance = await Exchange.init('binance', 111) const bybit = await Exchange.init('bybit', 111)
监听WebSocket价格事件时出现异常:后续触发binance平台的事件时,输出的平台标识却显示为bybit,与预期不符。
错误根源
1. 静态方法误用类属性存储实例
init方法中使用this.instance = new Exchange(...),这里的this在静态方法中指向类本身,instance成为类的静态属性。第二次调用init时会覆盖第一次创建的实例,导致所有后续操作实际指向最后创建的那个实例(bybit)。
2. 事件回调错误访问类静态属性
回调中Exchange.platform试图访问类的静态属性,但Exchange类并未定义该静态属性,实际逻辑应该是访问当前bot关联的Exchange实例的platform属性。
修复方案
修复Exchange类
const ccxt = require('ccxt') const Events = require('events') class Exchange { constructor (platform, uid) { this.platform = platform this.uid = uid this.keys = {} this.exchange = null } static async init (platform, uid) { // 使用局部变量存储新实例,避免覆盖之前的实例 const instance = new Exchange(platform, uid) // 检查当前实例的keys,而非类的静态属性 if (!instance.keys || !instance.keys[platform]) { await instance.fetchKeys(uid) } instance.setExchange(platform) return instance } async fetchKeys (uid) { // 模拟数据库返回密钥 this.keys = { binance: { key: 'apikey', secret: 'apisecret' }, bybit: { key: 'apikey', secret: 'apisecret' }, kukoin: { key: 'apikey', secret: 'apisecret' } } } setExchange (platform) { this.exchange = new ccxt[platform]({ apiKey: this.keys[platform].key, secret: this.keys[platform].secret }) } }
修复事件回调
// 假设bot对象关联了对应的Exchange实例(如bot.exchange) const onWsPriceEventCallback = async (event, bot) => { const { platform, symbol, price } = event if (bot.symbol === symbol && bot.platform_id === platform) { // 访问bot关联的Exchange实例的platform属性 console.log(`Bot #${bot.id} - Platform requested: ${platform} - Platform received: ${bot.exchange.platform} - Price: ${price} ${symbol}`) } } // 确保每个事件触发时处理对应bot(示例:遍历所有bot) Events.on('price', (event) => { bots.forEach(bot => onWsPriceEventCallback(event, bot)) })
修复说明
- 静态方法
init改用局部变量存储新实例,保证每次调用都创建独立的实例,不会互相覆盖。 - 密钥检查逻辑改为判断当前实例的
keys属性,避免混淆类静态属性与实例属性。 - 事件回调中从bot关联的Exchange实例获取平台标识,确保每个bot对应自己的实例数据。
内容的提问来源于stack exchange,提问作者aspirinemaga
相关产品推荐
相关产品推荐

