1. 问题1:定时器真的能准确定时吗?
示例:给 id = “btn” 的按钮绑定时间监听,执行定时器
<script type="text/javascript">
document.getElementById('btn').onclick = function () {
var start = Date.now()
console.log('启动定时器前...')
setTimeout(function () {
console.log('定时器执行了', Date.now()-start) //200ms后输出距离开始定时之前的毫秒数
}, 200)
console.log('启动定时器后...')
}
</script>
输出结果:
结论:我们的定时器理论上是在200ms后执行,并且输出距离定时器执行之前的时间 ===>> 即200;
但是,实际输出了202,跟我们预期的不一样。
定时器并不能保证真正定时执行,一般会延迟一丁点(可以接受),也有可能延迟很长时间(不能接受)
示例:延迟长时间的情况
<script type="text/javascript">
document.getElementById('btn').onclick = function () {
var start = Date.now()
console.log('启动定时器前...')
setTimeout(function () {
console.log('定时器执行了', Date.now()-start) //200ms后输出距离开始定时之前的毫秒数
}, 200)
console.log('启动定时器后...')
// // 做一个长时间的工作
for (var i = 0; i < 1000000000; i++) { //执行一个很多次数的循环,即占用一下js的执行顺序
}
}
</script>
结果:定时器延迟了1434ms,理论上应该是200ms
2. 如何证明js执行是单线程的
2.1 使用定时器和 alert 证明
<script type="text/javascript">
setTimeout(function () {
console.log('timeout 2222')
}, 5000)
setTimeout(function () {
console.log('timeout 1111')
}, 3000)
setTimeout(function () {
console.log('timeout() 00000')
}, 0)
function fn() {
console.log('fn()')
}
fn()
console.log('alert()之前')
alert('------')
console.log('alert()之后')
</script>
执行结果:
结论:
a. setTimeout()的回调函数是在主线程执行的
b. 定时器回调函数只有在运行栈中的代码全部执行完后才有可能执行
c. alert 会暂停当前主线程的执行, 同时暂停计时, 点击确定后, 恢复程序执行和计时
3. js引擎执行代码的基本流程
a. 先执行初始化代码: 包含一些特别的代码 回调函数(异步执行) ==>> 不管初始化代码执行多长时间,如第一个示例中的for循环(执行的比较久)
如: 设置定时器设置,绑定事件监听、发送ajax请求
b. 后面在某个时刻才会执行回调代码 ==>> 可能立即执行,也可能是隔一段时间执行(定时器)
4. 为什么js要用单线程模式, 而不用多线程模式?
JavaScript的单线程,与它的用途有关。 作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。 这决定了它只能是单线程,否则会带来很复杂的同步问题
如:页面中有一个 p 标签,它有一个修改和删除操作;首先,js先执行修改操作,但在修改的过程中某一个时刻,多线程导致删除操作执行了,这是修改操作就会报错。
文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!