setTimeout运行机制

作者: 吃一小勺 | 来源:发表于2017-05-19 21:39 被阅读0次

setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。

var timerId = setTimeout(func|code, delay)

判断以下代码的输出结果

var start=Date.now();
setTimeout(function(){
  var end=Date.now();
  console.log(end-start+'ms');
},2000);
console.log('1');

做一个猜测,JS引擎是按照代码块来顺序执行的,那么输出会是“延迟时间”>>"1"吗?结果却是相反的"1">>“延迟时间"

image.png

再做一个猜测,setTimeout里的代码输出之所以在后是因为它设置了将近两秒的延迟时间吗?如果setTimeout设置的延迟时间小于普通代码的运行时间,那么会不会先执行setTimeout里的代码呢?

var start=Date.now();
for (var i = 0; i < 30000; i++) {
  console.log(1);
}
var end=Date.now();
console.log(''+end-start+'ms');

以上代码打印30000个1,运行用了将近4504ms


image.png

我们在上述代码前加入一个定时器

var start=Date.now();
setTimeout(function(){
  var end=Date.now();
  console.log(end-start+'ms');
},2000);
for (var i = 0; i < 30000; i++) {
  console.log(1);
}
var end=Date.now();
console.log(''+end-start+'ms');

猜测:定时器设定的延迟时间为2000ms,小于普通代码运行时间,那么定时器中的代码是否会先输出呢?结果:虽然定时器设置的延迟时间小于普通代码的运行时间,执行结果仍然是先输出普通代码运行结果

image.png

定时器设置的延迟时间为2000ms,实际延迟了4597ms和普通代码的运行时间近乎相等,也可以说在普通代码运行结束后,定时器中的代码立刻执行。这是因为从它被载入到执行的时间超过了预设的2000ms,所以一遇到机会就尽快执行。
再做一个测试,把定时器和普通代码的位置调换

var start=Date.now();
for (var i = 0; i < 30000; i++) {
  console.log(1);
}
var end=Date.now();
console.log(''+end-start+'ms');
setTimeout(function(){
  var end=Date.now();
  console.log(end-start+'ms');
},2000);

这次定时器里的代码在普通代码执行结束后,延迟将近两秒执行。可以说明定时器设定的延迟时间从它被载入的那一刻开始计算。


image.png
结论1:定时器里的代码遇到普通代码不论设定的延迟时间为多少,都得等普通代码统统执行结束,才执行。因此如果普通代码执行时间太久,定时器里的代码能不能执行是不确定的。

打个比喻:普通代码是主线,定时器是副线,规则是先把主线任务做完再来做副线任务。那么两个副线任务(定时器)相遇,先做哪个呢?是根据代码块顺序判断,还是延迟时间?

var start=Date.now();
setTimeout(function(){
  var end=Date.now();
  console.log('定时器1');
  console.log(end-start+'ms');
},4000);
setTimeout(function(){
  var end=Date.now();
  console.log('定时器2');
  console.log(end-start+'ms');
},2000);

代码块顺序定时器1在定时器2前面,执行结果:先输出定时器2再输出定时器1


image.png

结论2:两个副线任务(定时器)相遇,无论代码块顺序,延迟时间到了就执行

《《鄙人之粗见。。。。。多多指教

相关文章

网友评论

    本文标题:setTimeout运行机制

    本文链接:https://www.haomeiwen.com/subject/dfzmzttx.html