繁体   English   中英

如何在发出的事件调用函数之外调用函数

[英]How to call a function outside of an emitted event call function

如果这不清楚,我很抱歉,已经晚了,我不知道如何最好地解释它。

我正在使用事件发射器将数据从服务器响应传递到另一个文件中单独类中的函数,但是当尝试使用这些类中的方法时, this关键字显然不起作用(因为在这种情况下, this是指服务器事件发射器) - 我将如何在类本身中引用函数? 我提供了代码来帮助更好地说明我的观点

服务类.js

class StreamService {
  /**
     *
     * @param {} database
     * @param {Collection<Guild>} guilds
  */
  constructor (database, guilds,) {
      .....
      twitchListener.on('live', this.sendLiveAlert) // fire test method when we get a notification
      // if there are streamers to monitor, being monitoring
      winston.info('Stream service initialized')
  }

  ..............

  async get (url, params = null, headers = this.defaultHeaders) {
    // check oauth token
    const expirationDate = this.token.expires_in || 0
    if (expirationDate <= Date.now() || !this.token) await this.getAccessToken()
    // build URL
    const index = 0
    let paramsString = ''
    for (const [key, value] of params.entries()) {
      if (index === 0) {
        paramsString += `?${key}=${value}`
      } else {
        paramsString += `&${key}=${value}`
      }
    }
    const res = await fetch(url + paramsString, { method: 'GET', headers: headers })
    if (!res.ok) {
      winston.error(`Error performing GET request to ${url}`)
      return null
    }
    return await res.json()
  }

  async sendLiveAlert(streamTitle, streamURL, avatar, userName, gameId, viewerCount, thumbnail, startDateTime) {
    // get game name first (no headers needed)
    const params = new Map()
    params.set('id', gameId)
    const gameData = await this.get('https://api.twitch.tv/heliix/games', params, this.defaultHeaders)
    if(gameData) {
      // get webhook and send message to channel
      const webhookClient = new WebhookClient('755641606555697305', 'OWZvI01kUUf4AAIR9uv2z4CxRse3Ik8b0LKOluaOYKmhE33h0ypMLT0JJm3laomlZ05o')
      const embed = new MessageEmbed()
        .setTitle(`${userName} just went live on Twitch!`)
        .setURL(streamURL)
        .setThumbnail(avatar)
        .addFields(
          { name: 'Now Playing', value: gameData.data[0].name },
          { name: 'Stream Title', value: streamTitle }
        )
        .setImage(thumbnail)
    }
    webhookClient.send('Webhook test', embed)
  }
}

服务器.js

class TwitchWebhookListener extends EventEmitter {
    ......................
    // Routes
    server
      .post((req, res) => {
        console.log('Incoming POST request on /webhooks')
              ............................
                const data = req.body.data[0]
                if(!this.streamerLiveStatus.get(data.user_id) && data.type === 'live') {
                  // pass request body to bot for processing
                  this.emit(
                    'live',
                    data.title, // stream title
                    `https://twitch.tv/${data.user_name}`, // channel link
                    `https://avatar.glue-bot.xyz/twitch/${data.user_name}`, // streamer avatar
                    data.user_name,
                    data.game_id,
                    data.viewer_count,
                    data.thumbnail_url,
                    data.started_at // do we need this?
                  )
                }
                break
              default:
                res.send(`Unknown webhook for ${req.params.id}`)
                break
            }
          } else {
            console.log('The Signature did not match')
            res.send('Ok')
          }
        } else {
          console.log('It didn\'t seem to be a Twitch Hook')
          res.send('Ok')
        }
      })
  }
}

const listener = new TwitchWebhookListener()
listener.listen()

module.exports = listener

sendLiveAlert方法中,我试图调用 StreamService 类的 get 方法 - 但因为它是通过server.js的发射器直接调用的, this特指Server.js类 - 有什么方法可以使用StreamService.get() ? 我显然可以重写方法本身内部的代码,但是当它就在那里时似乎没有必要?

改变这个:

twitchListener.on('live', this.sendLiveAlert)

对此:

twitchListener.on('live', this.sendLiveAlert.bind(this))

或者,您也可以这样做:

twitchListener.on('live', (...args) => {
    this.sendLiveAlert(...args);
});

使用.bind()它创建一个函数包装器,为您重置this的正确值。 在箭头函数的情况下,它为您保留了this的词法值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM