【问题标题】:setTimeout() and function scopesetTimeout() 和函数范围
【发布时间】:2021-01-20 20:10:51
【问题描述】:

所以我目前正在参加赫尔辛基大学的 fullstackOpen 课程,在做其中一个练习(这是关于显示和隐藏通知的 redux 函数)时,我偶然发现了一个令我感到困惑的概念:

假设我有一个按钮,单击该按钮需要 2 秒钟才能在控制台上打印“单击”。如果我使用 setTimeout 来“等待”这两秒钟,同时,我再次单击按钮,堆栈中的“setTimeout”逻辑就会出错。我找到的解决方案是创建一个“检查”变量来控制按钮是否已被单击,如果是,则在它再次设置关闭时间之前 clearTimeout()。

它工作得很好,但是,直到我找到正确的解决方案,我一直试图在创建异步代码的函数中插入“timeoutCheck”......为什么它只在变量超出范围时才有效的功能?有没有更好的解决方案?我想我错过了什么。

这是一个丑陋的普通例子,就像课程中的情况一样。我正在“模拟”用户在按钮中连续点击三次,如果变量在函数内,我们会遇到错误的情况,而如果变量在函数外,即使用户点击了三次连续几次,只计算第一个。 如果需要,我可以提供整个 redux 应用程序。

无效的代码:

activateTime = () => {
    let timeoutCheck

    if(timeoutCheck){
        clearTimeout(timeoutCheck)
    }

    timeoutCheck = setTimeout(() => console.log('clicked'), 2000)
}

const button = document.createElement('button')
button.addEventListener('click', () => activateTime())
setTimeout(() => button.click(), 250)
setTimeout(() => button.click(), 350)
setTimeout(() => button.click(), 450)

有效的代码:

let timeoutCheck

activateTime = () => {
    if(timeoutCheck){
        clearTimeout(timeoutCheck)
    }

    timeoutCheck = setTimeout(() => console.log('clicked'), 2000)
}

const button = document.createElement('button')
button.addEventListener('click', () => activateTime())
setTimeout(() => button.click(), 250)
setTimeout(() => button.click(), 350)
setTimeout(() => button.click(), 450)

【问题讨论】:

  • 因为当它在里面时,它每次都会创建一个新变量。
  • 如果在函数内部声明变量,每次运行函数都会得到一个新变量,它没有上次运行的值。
  • 这能回答你的问题吗? What is the scope of variables in JavaScript?

标签: javascript asynchronous settimeout


【解决方案1】:

每次调用activateTime 时,它都会初始化变量timeoutCheck,所以它总是undefined。你可以尝试这样的闭包:

const activateTimeClosure = () => {
 let timeoutCheck

 return {
   activateTime () {
    if(timeoutCheck){
        clearTimeout(timeoutCheck)
    }

    timeoutCheck = setTimeout(() => console.log('clicked'), 2000)
   }
 }
}
const { activeTime } = activateTimeClosure()
const button = document.createElement('button')

button.addEventListener('click', () => activateTime())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多