【问题标题】:Stay within the scope of the class when using setInterval in javascript在 javascript 中使用 setInterval 时保持在类的范围内
【发布时间】:2017-09-29 15:05:16
【问题描述】:

我有一个类来管理我在 NodeJS 中与我的套接字的连接。每当连接无法建立或丢失时,我想设置一个间隔以继续重试连接。但是,如果我调用setInterval 函数,我作为引用传递的方法现在在setInterval 的范围内。我的套接字类中的方法现在不再可用,除非我有一些巨大的嵌套语句,否则我无法重新连接套接字。主要问题是我在connect() 方法中创建的事件监听器现在在setInterval() 的范围内不再可用。

关于如何让它发挥作用的任何想法?

class SocketClass {

  constructor() {
    this.socket = {}
    this.port = 0
    this.host = ''
    this.intervalID = null
  }


  connect(port, host) {
    this.port = port;
    this.host = host;
    this.connectImpl()
    this.socket.on('error', () => this.errorEventHandler())
    this.socket.on('close', () => this.closeEventHandler())
  }

  connectEventHandler() {
    console.log('Connected!')
    if (this.intervalID !== null) {
      clearInterval(this.intervalID);
    }
  }

  errorEventHandler() {
    console.log('Error!')
  }

  connectImpl() {
    console.log('Trying to connect...')
    this.socket = require('net').Socket().connect(this.port, this.host)
  }

  closeEventHandler() {
    console.log('Connection lost')
    this.intervalID = setInterval(() => this.connectImpl(), 1000)
    // this.connectImpl() is called correctly but the event 
    // handlers defined in the constructor are now no longer bound
  }

}

export default new SocketClass

【问题讨论】:

  • 我发现反对票难以置信地难以理解。我的问题很简单,包括代码。有些人真的很喜欢砸那个否决按钮..
  • 击败了我——有人也对我完美的答案投了反对票……
  • 至于明确:“我作为参考传递的方法现在在 setInterval 的范围内” - 不,这是不正确的。 “我的套接字类中的方法现在不再可用” - 也不正确。 “我在 connect() 方法中创建的事件侦听器现在在 setInterval() 的范围内不再可用” - 也不正确。

标签: javascript node.js sockets


【解决方案1】:

尽管您的评论说了什么,但您实际上并没有调用您的 connectImpl 处理程序:

this.intervalID = setInterval(() => this.connectImpl(), 1000)

没有额外的括号,你只是传递一个箭头函数的引用,返回一个对connectImpl函数的引用

回复:您的编辑 - 您需要将事件处理程序注册移动到 connectImpl() 方法中。当您的计时器触发这些处理程序时,这些处理程序仍然注册在 old 套接字上(但在垃圾收集时会消失)并且当前写入的不是附加到新创建的套接字。这不是范围相关的问题。

您还需要确保在创建新计时器之前在closeEventHandler 中调用clearInterval(this.intervalID),因为“关闭时”处理程序也称为“错误时”(至少对于某些错误)。

【讨论】:

  • 我不小心粘贴了代码,但仍然有错字。评论是正确的。括号已经包含在我的 IDE 的代码中。尽管如此,在我最初的帖子中,我清楚地表明我的课程范围在 setInterval() 中不再可用,这是我要解决的问题。
  • 我回答了您当时提出的问题。您的另一个问题是您需要在 connectImpl 方法中注册这些处理程序 - 您第一次连接到的带有处理程序的 this.socket 实例在您重新连接时不是同一个实例。
  • 你实际上没有,因为从我的问题很明显我知道这些处理程序没有在setInterval() 的范围内注册。除此之外,在connectImpl 中注册它们会导致内存泄漏,因为如果我没有连接,我会经常使用该方法。
  • 您说您遇到了范围问题。你没有。在connectImpl 中注册处理程序也不会造成泄漏,因为它们附加到一个刚刚创建的对象,并且该对象的前一个实例将被垃圾收集。您不能重新分配给this.socket,并期望先前注册的处理程序随后将附加到新套接字。
猜你喜欢
  • 2010-12-25
  • 2014-08-22
  • 1970-01-01
  • 2010-10-19
  • 2015-10-21
  • 2018-07-13
  • 2012-01-28
  • 1970-01-01
  • 2011-03-26
相关资源
最近更新 更多