JS关于 setTimeout 函数

JavaScript 中的 setTimeout() 可用来延迟执行一段代码,但结合 JS 的运行原理,留下了一些坑

先打印了 Hello 再打印 Hello World,setTimeout(0) 似乎不是立即执行的

setTimeout( function() {
  console.log("Hello World");
}, 0)
console.log('Hello');

打印
task finished.
Time elapsed: 502 ms

var start = new Date();
setTimeout(function(){
    var end = new Date();
    console.log("Time elapsed: ", end - start, "ms");
}, 500);

console.log("task finished.");

运行下面这段脚本能够看到:Time elapsed的值大概在1001ms左右,肯定会超过1000ms。也就是说:setTimeout失效了,指定的函数并没有在500ms后运行。而是延迟到1000ms后才运行。

var start = new Date();
setTimeout(function(){
    var end = new Date();
    console.log("Time elapsed: ", end - start, "ms");
}, 500);

while (new Date - start <= 1000)
{

}

setTimeout没有执行,陷入了死循环

var t=true;
setTimeout(function(){
	t=false;
},1000);
while(t){
}
console.log('end');

下面是网上的一些解释

JavaScript 是单线程运行的,也就是无法同一时候运行多段代码。当某一段代码正在运行的时候,全部兴许的任务都必须等待,形成一个队列,一旦当前任务运行完毕,再从队列中取出下一个任务。假设这个时间设为 0,就代表马上插入队列,但不是马上运行。仍然要等待前面代码运行完成。所以 setTimeout 并不能保证运行的时间。是否及时运行取决于 JavaScript 线程是拥挤还是空暇。

这里绑定了 keydown 事件,意图是当用户在文本框里输入字符时。将输入的内容实时地在 div 中显示出来。可是实际效果并不是如此,能够发现。每按下一个字符时,div 中仅仅能显示出之前的内容,无法得到当前的字符。

<input type="text" onkeydown="show(this.value)">
<div></div>
<script type="text/javascript">
  function show(val) {
    document.getElementsByTagName('div')[0].innerHTML = val;
  }
</script>

这段代码使用了setTimeout(0)就能够实现需要的效果了。

<input type="text" onkeydown="var self=this; setTimeout(function() {show(self.value)}, 0)">
<div></div>
<script type="text/javascript">
  function show(val) {
    document.getElementsByTagName('div')[0].innerHTML = val;
  }
</script>

这里事实上涉及2个任务,1个是将键盘输入的字符回写到输入框中。一个是获取文本框的值将其写入div中。第一个是浏览器自身的默认行为。一个是我们自己编写的代码。非常显然。必需要先让浏览器将字符回写到文本框。然后我们才干获取其内容写到div中。改变顺序,这这正是 setTimeout(0) 的作用。

经我测试,实际应用中,setTimeout 的 millisec 参数不管你设置多少,实际执行都是在线程的最后,因为在执行一个操作的时候,JavaScript 肯定是一直把代码执行完后再走 setTimeout 绑定的 code 的。只有调用多个 setTimeout 的时候,执行顺序才是按照设置的时间走

猜你喜欢

转载自blog.csdn.net/HAIYUANBOY/article/details/88090855
今日推荐