加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

定时器和ajax

发布时间:2020-12-16 03:23:48 所属栏目:百科 来源:网络整理
导读:JS中关于定时器,有两种: setTimeout 和 setInterval ,区别在于单次与循环. 众所周知,JS运行在单线程的环境中,也就没有什么并行处理的说法. 既然是单线程,那么肯定有个队列(FIFO)来排列代码的执行顺序,要不然一拥而上去抢购,那程序肯定 crash. 先来看一段代码

JS中关于定时器,有两种: setTimeoutsetInterval,区别在于单次与循环.
众所周知,JS运行在单线程的环境中,也就没有什么并行处理的说法. 既然是单线程,那么肯定有个队列(FIFO)来排列代码的执行顺序,要不然一拥而上去抢购,那程序肯定 crash.
先来看一段代码:

for(var i=0; i<5; i++){
    setTimeout(function(){
        console.log(i);
    },0);
}

不妨想一下,这段代码的执行结果是多少. 年初去携程面试的时候,面试官给的题. 当时太青涩,只会吹牛,却不会庖丁解牛,自然被pass咯. 当时我给出的回答是0,1,2,3,4. 面试官呵呵一笑,打印后是5,5,5.

如上图所述,console.log(i)这条语句,只是在时隔特定时间后,才插入JS进程时间的队列,并不是立刻执行.
打个比方: 你要去一个很火的饭店(已满座)吃饭,到前台后,肯定是先领号码,当服务员叫到你的号码之后,你才能进去找空座坐下,此时你仍然不能立刻吃饭,还得等厨师(只有一个)做你的菜,菜做完,端上桌,你才能吃饭.
饭店===JS进程时间线
号码===特定时间(即定时器的第二个参数)
坐定===回调函数被插入时间线队列,并等待执行
做菜===队列中排在前面的操作执行完毕
吃饭===执行本次定时器的回调操作

关于定时器要记住的最重要的事情是: 指定的时间间隔表示何时将定时器的代码添加到队列,而不是何时执行代码. - - -《JavaScript高级程序设计》(第三版) Page610

如果弄懂上面这句话,那道面试题就很好理解了. 在循环当中,肯定首要处理循环,所以每次循环后,定时器中的代码都被放入队列中,等待循环执行完毕,再执行队列中的console. 而循环执行完毕时,此时i===5,所以输出5个5 .
如果仍然要利用定时器输出0,4,可以对上面代码做如下改造:

for(var i=0; i<5; i++){
    (function(arg){
        setTimeout(function(){
            console.log(arg);
        },0);
    })(i);
}

这就利用了闭包函数的特性了,立即执行.

有了上面的基础后,再说个跟ajax有关的,请看代码:

var xhr = new XMLHttpRequest();
xhr.open("get","js/jquery.min.js",true);
xhr.onreadystatechange = function(){
    if (xhr.readyState == 4){
        if (xhr.status == 200){
            console.log("ajax");
        }
    }
}
xhr.send();

setTimeout(function(){
    console.log("定时器");
},0);

打印顺序是什么呢?
ajax
定时器
?
但是很”不讲道理”的,顺序却是:

定时器
ajax

其实这是合理的,xhr.send();这个方法的确在定时器前面执行,但是xhr.onreadystatechange这是一个回调函数,也就是说请求后,不管成功失败,都会进这个方法. 而发送请求时,却是走的网络通信那一块了,跟JS代码基本没有关系,所以此时JS代码处于空闲状态,就会执行队列中的方法. 等到请求完毕,才执行xhr.onreadystatechange方法. 所以顺序自然是定时器在前,ajax在后.

setInterval 循环定时器就比较复杂了,之后有时间再写吧.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读