【问题标题】:Cancelling setInterval from different places (NodeJS variable scope)从不同的地方取消 setInterval(NodeJS 变量范围)
【发布时间】:2017-09-21 14:12:41
【问题描述】:

我正在设置一个全局变量,然后使用可以从模块的其他位置调用的函数在其中存储一个 setInterval。我还设置了一个函数来取消 setInterval,该函数可用于从模块内的其他函数中取消 setInterval。请看下面的sn-p:

var availabilityCheckInterval

function repeatAvailabilityCheckStart (session) {
  availabilityCheckInterval = setInterval(() => {
    // Call an API
    if (successful) {
      repeatAvailabilityCheckStop()
    }
  }, 15000)
}

function repeatAvailabilityCheckStop () {
  clearInterval(availabilityCheckInterval)
}

这在我的本地机器和暂存环境上工作,但似乎在并发用户的生产中失败(或者它可能从未真正工作过......)。

我在这里遗漏了与变量范围相关的内容吗?我在有并发用户的生产环境中使用setInterval() 太天真了?

【问题讨论】:

  • 为什么不让repeatAvailabilityCheckStart 将整数句柄返回给调用者,让他们取消呢?为什么不做任何事情的变量?您甚至可以,因为这些操作涉及间隔的 state,所以将它们包装在一个带有每个请求实例的类中。 20 美元表示您的生产失败来自那个“全局”(顶级变量在 Node.js 中实际上并不是全局的)。
  • 变量的想法是将间隔存储在具有全局范围的变量中,以便可以在多个不同的地方取消它。我没有想过实际上将间隔句柄返回给调用者。当您说将它们包装在一个对象中时,请执行以下操作: var whatever = { startInterval: () => { setInterval(() => {}, 2000) } }?

标签: javascript node.js scope


【解决方案1】:

当我在 cmets 中说“将其包装在一个对象中”时,我的意思是这样的:

class Interval {
  constructor (f, n) {
    this.fn = f;
    this.repeatInterval = n;
    this.handle = null;
  }

  get running () {
    return this.handle !== null;
  }

  run (...args) {
    if (!this.running) {
      this.handle = setInterval(this.fn, this.repeatInterval, ...args);
    } else {
      // optionally throw, display msg, whatever
    }
    return this;
  }

  stop () {
    clearInterval(this.handle);
    this.handle = null;
    return this;
  }
}

现在您可以拥有每个请求的句柄/间隔。在每个请求上做

let intvl = new Interval(someFn, 15000).run();

并清理:

intvl.stop();

【讨论】:

  • 感谢您的宝贵时间,杰瑞德。我不知道你可以从 OOP 的角度来处理 setInterval。
  • @tombraider 没问题。我通常不是一个 OOP 类型的人,但在这种情况下它确实很有意义:你有一个状态(间隔是否正在运行)和一些操作来操作它。
猜你喜欢
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 2015-08-20
  • 2015-11-04
  • 1970-01-01
  • 2019-01-30
  • 2020-07-24
  • 1970-01-01
相关资源
最近更新 更多