簡體   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