【问题标题】:ClearInterval not within scopeClearInterval 不在范围内
【发布时间】:2022-01-05 10:29:46
【问题描述】:

我正在尝试有条件地清除和设置Interval。但是,当我这样做时,似乎 clearInterval 看不到 setInterval。

当我将清除间隔移出 if 语句时,它可以工作,但现在不能再有条件地清除设置的间隔。我在这里错过了什么?

// Called when user clicks on menu item
const loadQueueStatus = async () => {
  // This function will fetch queueStatus data
  const queueStatus = async () => {
    // eslint-disable-next-line
    const queueStatus = await getQueueStatus().then((data) => {
      this.setState({queueStatus: data})
    });
  }

  console.log("state is: ", this.state.isVolunteerStatusOpen)
  // call the queue right away if the menu just opened, we know if it is opened as state would still say false
  // We do this so we don't wait 5 seconds for the first fetch.
  if(!this.state.isVolunteerStatusOpen) {
    queueStatus()
  }

  //Set a listener, to pole the data while menu is open
  let setListener = setInterval( queueStatus, 5000);
  // If the menu is closed, the state will be true, if so, clear the listener
  if(this.state.isVolunteerStatusOpen) {
    console.log("clearing listener")
    clearInterval(setListener);
  }
  // Extra caution to clear listener
  setListener = null

  // Inform state of status window status for next click
  this.setState({
  isVolunteerStatusOpen: !this.state.isVolunteerStatusOpen
  })
}

【问题讨论】:

  • 该示例未显示问题。请确保代码是minimal reproducible example
  • 抱歉,我不明白。这就是问题所在。如果我要运行它,setInteral 不会停止,它会继续运行函数 queueStatus。
  • 我们无法复制您从提供的代码中描述的问题。因此,提供帮助变得更加困难
  • 好的,我添加了整个块。
  • 抱歉,仔细阅读代码后,我发现了问题。当我清除间隔时,我已经创建了一个新的侦听器。回到绘图板

标签: javascript reactjs setinterval


【解决方案1】:

在我上面的代码中,我在清除它之前创建了一个新的 setInterval 函数。但是,真正的问题是每次设置 setInterval 时,都会为该 setInterval 创建一个新 ID。即使您将 setInterval 存储在一个变量中,每次创建 setInterval 时,您都会获得一个新 ID 并失去对旧 ID 的引用,该 ID 仍存在于内存中

为了解决这个问题,在我设置状态的代码末尾,我将等于 setInterval 的变量传递给状态。因此,如果变量等于 33,则将其传递给 state。当我清除间隔时,我在状态中引用此 ID。

// Called when user clicks on menu item
const loadQueueStatus = async () => {
  // This function will fetch queueStatus data
  const queueStatus = async () => {
    // eslint-disable-next-line
    const queueStatus = await getQueueStatus().then((data) => {
      this.setState({queueStatus: data})
    });
  }

  // call the queue right away if the menu just opened, we know if it is opened as state would still say false
  // We do this so we don't wait 5 seconds for the first fetch.
  let setIntervalFunction
  if(!this.state.isVolunteerStatusOpen) {
    queueStatus()
    setIntervalFunction = setInterval( queueStatus, 5000);
  }

  console.log(setIntervalFunction)

  //Set a listener, to pole the data while menu is open
  
  // If the menu is closed, the state will be true, if so, clear the listener
  if(this.state.isVolunteerStatusOpen) {
    console.log("clearing listener")
    clearInterval(this.state.setIntervalFunction);
  }

  // Inform state of status window status for next click
  this.setState({
  isVolunteerStatusOpen: !this.state.isVolunteerStatusOpen,
  setIntervalFunction: setIntervalFunction //Stores reference to setInterval so it can be cleared next time function is called.
  })
}

【讨论】:

    猜你喜欢
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多