• JavaScript:异步 setTimeout


    setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。

    function showDate(){
    var date=new Date();
    console.log(date);
    }
    console.log("aa");
    showDate();
    console.log("bb");
    setTimeout(function(){showDate();},10000);
    console.log("cc");
    showDate();

    可以发现setTimeout内部的function是等待10s以后再执行的。

    把时间改为0

     发现它还是最后执行的

    类似异步

    更具体的,更详细的

    Date.prototype.format = function(formatStr) 
    {   
        var str = formatStr;   
        var Week = ['','','','','','',''];  
      
        str=str.replace(/yyyy|YYYY/,this.getFullYear());   
        str=str.replace(/yy|YY/,(this.getYear() % 100)>9?(this.getYear() % 100).toString():'0' + (this.getYear() % 100));   
        //
        this.setMonth(this.getMonth()+1);
        str=str.replace(/MM/,this.getMonth()>9?this.getMonth().toString():'0' + this.getMonth());   
        str=str.replace(/M/g,this.getMonth());   
      
        str=str.replace(/w|W/g,Week[this.getDay()]);   
      
        str=str.replace(/dd|DD/,this.getDate()>9?this.getDate().toString():'0' + this.getDate());   
        str=str.replace(/d|D/g,this.getDate());   
      
        str=str.replace(/hh|HH/,this.getHours()>9?this.getHours().toString():'0' + this.getHours());   
        str=str.replace(/h|H/g,this.getHours());   
        str=str.replace(/mm/,this.getMinutes()>9?this.getMinutes().toString():'0' + this.getMinutes());   
        str=str.replace(/m/g,this.getMinutes());   
      
        str=str.replace(/ss|SS/,this.getSeconds()>9?this.getSeconds().toString():'0' + this.getSeconds());   
        str=str.replace(/s|S/g,this.getSeconds()); 
        
        str=str.replace(/ffff/,this.getMilliseconds());
      
        return str;   
    }   
    
    function showDate(){
    var date=new Date();
    var str=date.format("yyyy-MM-dd HH:mm:ss:ffff");
    console.log(str);
    }
    console.log("aa");
    showDate();
    console.log("bb");
    setTimeout(function(){showDate();},1000);
    console.log("cc");
    showDate();

    时间为100微秒

    差距都差不多,更setTimeout间隔时间无关.

    那么setTimeout是不是就是运行到setTimeout时就在任务队列中添加一个方法,setTimeout时间到了就运行该方法?

    其实发现不是

    有特殊情况:

    假如setTimeout的间隔时间小于任务队列后面运行的时间:

    function showDate(){
    var date=new Date();
    var str=date.format("yyyy-MM-dd HH:mm:ss:ffff");
    console.log(str);
    }
    console.log("aa");
    showDate();
    console.log("bb");
    setTimeout(function(){console.log("bbb");showDate();},3000);
    console.log("cc");
    showDate();
    console.log("begin");
    for(var i=0;i<10000000;i++){
    }
    console.log("end");
    showDate();

     发现:setTimeout的间隔时间是近5.5s,for循环花费的时间也大概是5.5s

    说明:在这种setTimeout间隔时间小于任务队列运行时间的情况下,setTimeout中的方法一直到队列任务全部完成以后才执行,间隔时间有任务队列花费时间决定。

    setTimeout间隔时间大于队列任务运行时间,实际任务中大部分是这种情况

    function showDate(){
    var date=new Date();
    var str=date.format("yyyy-MM-dd HH:mm:ss:ffff");
    console.log(str);
    }
    console.log("aa");
    showDate();
    console.log("bb");
    setTimeout(function(){console.log("bbb");showDate();},30000);
    console.log("cc");
    showDate();
    console.log("begin");
    for(var i=0;i<10000000;i++){
    }
    console.log("end");
    showDate();

    发现尽管for循环中花费了5.5s,但是setTimeout的间隔时间依然是30s.

    这时再回头看看那个setTimeout(function(){},0),间隔时间是0的情况

    发现setTimeout中的方法就应该在任务队列的最后运行。

    证明:js引擎按照预编译的顺序运行队列任务,这时setTimeout中的方法没有在队列中,间隔时间到了以后将setTimeout中的方法添加到任务队列中

    所以,setTimeout中的方法都是在预编译中的方法后运行的

    多个setTimeout中的方法运行顺序是由它们加入队列的顺序决定的。

    function showDate(){
    var date=new Date();
    var str=date.format("yyyy-MM-dd HH:mm:ss:f");
    console.log(str);
    }
    console.log("aa");
    showDate();
    console.log("bb");
    setTimeout(function(){console.log("bbb");showDate();},3000);
    console.log("cc");
    showDate();
    console.log("begin");
    for(var i=0;i<10000000;i++){
    }
    console.log("end");
    showDate();
    console.log("begin2");
    for(var i=0;i<10000000;i++){
    }
    console.log("end2");
    showDate();

    继续分析:

    1.两个setTimeout

    function showDate(){
    var date=new Date();
    var str=date.format("yyyy-MM-dd HH:mm:ss:ffff");
    console.log(str);
    }
    console.log("aa");
    showDate();
    console.log("bb");
    setTimeout(function(){console.log("bbb");showDate();},3000);
    console.log("cc");
    setTimeout(function(){console.log("ccc");showDate();},1000);
    showDate();

    2.第一个setTimeout的方法花费时间大于第二个setTimeout的间隔时间:

    function showDate(){
    var date=new Date();
    var str=date.format("yyyy-MM-dd HH:mm:ss:ffff");
    console.log(str);
    }
    console.log("aa");
    showDate();
    console.log("bb");
    setTimeout(function(){console.log("bbb");showDate();},3000);
    console.log("cc");
    setTimeout(function(){
    console.log("ccc");
    showDate();
    console.log("begin");
    for(var i=0;i<300000000;i++){
    }
    console.log("end");
    showDate();
    },1000);
    showDate();

    发现:for循环花费了6s多,bbb是紧接着前一个setTimeout方法的,

    http://www.cnblogs.com/littledu/articles/2607211.html

    http://www.laruence.com/2009/09/23/1089.html

    http://www.cnblogs.com/rubylouvre/archive/2009/08/20/1550264.html

    http://www.cnblogs.com/rubylouvre/archive/2011/03/14/1982699.html

  • 相关阅读:
    合并两个有序数组
    删除排序数组中的重复项 II
    对称二叉树
    相同的树
    二叉树的最大深度
    从前序与中序遍历序列构造二叉树
    vue简单案例_动态添加删除用户数据
    对vue的初步学习(一)
    关于java for循环常见练习题
    关于java中循环的学习
  • 原文地址:https://www.cnblogs.com/hongdada/p/3359668.html
Copyright © 2020-2023  润新知