Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

❤️❤️❤️Question022 -JavaScript、为什么要用 setTimeout 模拟 setInterval ? #22

Open
wangbinze opened this issue Mar 8, 2021 · 1 comment

Comments

@wangbinze
Copy link
Owner

题目:为什么要用 setTimeout 模拟 setInterval ?

@wangbinze
Copy link
Owner Author

setInterval推入任务队列的事件不准确

setInterval(fn(), N);  // fn()将在N秒之后被推入任务队列。

在 setInterval 被推入任务队列时,如果在它前面有很多任务或者某个任务等待时间较长比如网络请求等,那么这个定时器的执行时间和我们预定它执行的时间可能并不一致。

函数操作耗时过长导致的不准确

考虑极端情况,假如定时器里面的代码需要进行大量的计算(耗费事件较长),或者是DOM操作。这样一来,花的时间就比较长,有可能前一次代码还没有执行完,后一次代码就被添加到队列了。也会导致定时器变得不准确,甚至出现同一时间执行两次的情况。

setInterval 缺点 与 setTimeout 的不同

setTimeout和setInteval是window对象上两个主要的定时方法,他们的语法基本相同,但完成功能的却是不同的。

  • settimeout方法是定时程序,也就是在到达某个指定时间后,执行什么事。(执行一次就拉倒)
  • setinterval方法则是表示间隔一定时间反复执行某些事。
    • 再次强调,定时器指定的时间间隔,表示的是何时将定时器的代码添加到消息队列,而不是何时执行代码。所以真正何时执行代码的时间是不能保证的,取决于何时被主线程的事件循环取到,并执行。

每个 setTimeout 产生的任务会直接 push 到任务队列中;而 setInterval 在每次把任务 push 到任务队列前,都要进行一下判断(看上次的任务是否仍在队列中,如果有则不添加,没有则添加)。
因而我们一般用 setTimeout 模拟 setInterval ,来规避掉上面的缺点。

   const mySetInterval = (callbcak, time) => {
        (function inner() {
            const timer = setTimeout(() => {
                callbcak()
                clearInterval(timer)
                inner()
            }, time)
        })()
    }
     mySetInterval(() => {
        console.log(2)
    }, 3000)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant