You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确创建含异步初始化属性的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:35:42