关于setTimeout

31 阅读1分钟

在写防抖代码时:

function test(message){
    alert(message)
}
function debounce(fn){
    let timer = null
    return function(){
        console.log(arguments)
        console.log(this)
        if(timer){
            console.log('被打断的:',timer)
            console.log('计时还没结束')
            clearTimeout(timer)
            timer = null
        }
        timer = setTimeout(()=>{
            fn.apply(this,arguments)
        },2000)
        console.log('定义后的timer:',timer)
    }
}
const btn = document.querySelector('#btn')
const debounceTest = debounce(test)
btn.addEventListener('click',()=>{
    debounceTest('hello~')
})

在点击进行输出后,发现打印台打印是这样的:

image.png 一时开始疑惑,既然setTimeout是异步任务,那么应该先执行timer定义后的console.log('定义后的timer:',timer)输出应该是null才对,为什么输出会是setTimeout的返回值呢,查阅一些资料发现: 尽管setTimeout是异步执行的,但是它的返回值并不代表定时器的执行状态。它只是一个用于标识定时器的数字值,并且该值会立即被分配给变量 timer

因此,即使 setTimeout 是异步的,调用 console.log(timer) 时,定时器可能尚未执行,但你仍然可以看到先前分配的标识符值。实际上,这个标识符是在调用 setTimeout立即生成的,而不是在定时器执行时才分配。