关于setTimeout和setInterval的实现原理

首先来看setTimeout()的基本用法:

setTimeout(function(){
     console.log("ok!");
},1000)

参数1:要延迟执行的代码,也可以不选择。

参数2:延迟多少秒后执行。(其实这种说法是不准确的,实质是在一段时间后将当前任务加入到队列当中去)

上面代码的表现:在1秒以后将alert。


那么再看下面的代码

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

运行这段脚本可以看到:Time elapsed的值大概在1001ms左右,肯定会超过1000ms。也就是说:setTimeout失效了,指定的函数并没有在500ms后执行,而是延迟到1000ms后才执行。加入再把while中的内容改为new Date()-start>0,则会陷入死循环中,不会执行setTimeout里的函数。


再看下一段代码

function a()  
{  
    setTimeout(function(){console.log(1);},0);  
    console.log(2);  
}  
a();  

运行这段脚本可以看到:先打印2后打印1,我们在setTimeout里面指定了0ms,希望能立即执行,但是实际上没有效果。


再来一个典型例子

var j = 0;  
for(var i=0;i<5;i++){  
    setTimeout(function(){  
        console.log(j);  
        console.log(i);  
    },0);  
    j++;  
}  
输出:0 5 1 5 2 5 3 5 4 5。可以发现虽然延迟设为了0,但是不代表就会立即执行。setTimeout里的函数是在for循环完了以后才入栈的

原因:除了js是单线程执行这一点以外,对于javascript还维护着一个setTimeout队列,未执行的setTimeout任务就按出现的顺序放到setTimeout队列,等待普通的任务队列中的任务执行完才开始按顺序执行积累在setTimeout中的任务。就是说script脚本加载完成了之后,setTimeout才会执行注册的函数


JavaScript是单线程执行的,无法同时执行多段代码。当某一段代码正在执行的时候,所有后续的任务都必须等待,为了控制要执行的代码,就有了一个javascript的队列。这些任务会按照将他们添加到队列的顺序执行。而setTimeout()的第二个参数就是告诉javascript再过多长时间把当前任务(参数一)添加到队列中。注意:

如果队列是空的,那么添加的代码就会立即执行。

如果队列不是空的,那么就要等前面的代码执行完以后再执行。


也就是说setTimeout只能保证在指定的时间过后将任务(需要执行的函数)插入队列等候,并不保证这个任务在什么时候执行。执行javascript的线程会在空闲的时候,自行从队列中取出任务然后执行它。javascript通过这种队列机制,给我们制造一个异步执行的假象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值