zoukankan      html  css  js  c++  java
  • setTimeout详解

    https://www.cnblogs.com/wzndkj/p/7069331.html

    一、setTimeout基础

    setTimeout(func|code,delay);
    第一个参数表示将要推迟的函数名或者一段代码,第二个参数表示推迟执行的毫秒数
     
    复制代码
    eg:
    console.log(1);
    setTimeout('console.log(2)',1000);
    console.log(3);
    
    answer:
    1
    3
    2
    复制代码
     
    *:推迟的代码必须以字符串的形式,因为引擎内部使用eval()函数,将字符串转为代码。
    *:如果推迟执行的是函数,则可以直接将函数名,放入setTimeout()
     
    复制代码
    eg:
    function func(){
      console.log(2);
    }
    setTimeout(func,5000);
    //或者
    setTimeout(function(){
      console.log(2);
    },1000)
    复制代码

    *:如果写成setTimeout(func(),5000);func会立即执行

    二、setTimeout支持更多的参数
    复制代码
    eg:
    setTimeout(function(a,b){
      console.log(a+b);
    },1000,4,5)
    
    //4,5 9
    //'str' '2' str2
    复制代码
     
    *:从第三个参数开始,依次用来表示第一个参数(回调函数)传入的参数
    *:一些古老的浏览器是不支持,可以用bind或apply方法来解决
     
    eg:
    setTimeout(function(a,b){
      console.log(a+b);
    }.bind(this,4,5),1000)
     
    *:第一个参数表示将原函数的this绑定全局作用域,第二个参数开始是要传入原函数的参数
    *:当调用绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为 this
     
    三、setTimeout()中回调函数中的this
    复制代码
    eg:
    var a=1;
    var obj={
      a:2,
      b:function(){
        setTimeout(function(){
          console.log(this.a);
        },2000);
      }
    };
    obj.b();
    复制代码
     
    上面代码输出的是1,而不是2,表示o.b的this所指向的已经不是o,而是全局环境了
    可以用bind()来改变这个情况:
     
    复制代码
    var a=1;
    var obj={
        a:2,
        b:function(){
            setTimeout(function(){
                console.log(this.a);
            }.bind(this),2000);//注意这行
        }
    };
    obj.b();        
    复制代码
    四、setTimeout()执行回调间隔时间长度
     
    var startTime = new Date();
    setTimeout(function () {
        console.log(new Date() - startTime);
    }, 100);
     
    //100+ 取决于后面同步执行的JS需要占用多少时间
     
     
    五、setTimeout(func,0)
    复制代码
    eg:func1和func2谁会先执行?
    
    function func1(){
        console.log(1);
    }
    function func2(){
        console.log(2);
    }
    setTimeout(function () {
        func1();
    }, 0)
    func2();
    复制代码
    setTimeout(function(){
        func1()
    },0)
    setTimeout(function(){
        func1();
    })

    有什么差别?

    0秒延迟,此回调将会放到一个能立即执行的时段进行触发。javascript代码大体上是自顶向下的,但中间穿插着有关DOM渲染,事件回应等异步代码,他们将组成一个队列,零秒延迟将会实现插队操作。
    不写第二个参数,浏览器自动配置时间,在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。
     
     
     
    六、setTimeout和单线程
    首先需要注意javascript是单线程的,特点就是容易出现阻塞。如果一段程序处理时间很长,很容易导致整个页面hold住。什么交互都处理不了怎么办?

    setTimeout一个很关键的用法就是分片,如果一段程序过大,我们可以拆分成若干细小的块。
    例如上面的情况,我们将那一段复杂的逻辑拆分处理,分片塞入队列。这样即使在复杂程序没有处理完时,
    我们操作页面,也是能得到即使响应的。其实就是将交互插入到了复杂程序中执行。

    换一种思路,上面就是利用setTimeout实现一种伪多线程的概念

    有个函数库Concurrent.Thread.js 就是实现js的多线程的
    复制代码
    eg:Concurrent.Thread.create(function(){
        for(var i=0; i<100000000; i++){
            console.log(i);
        }
    })
    
    $('#test').click(function(){
        alert(1);
    });
    复制代码
    虽然有个巨大的循环,但是这时不妨碍你去触发alert();
    当我们需要渲染一个很复杂的DOM时,例如table组件,复杂的构图等等,
    假如整个过程需要3s,我们是等待完全处理完成在呈现,还是使用一个setTimeout分片,
    将内容一片一片的断续呈现。
    其实setTimeout给了我们很多优化交互的空间。
     
     
    七、如何使用
    setTimeout这么厉害,那么我们是需要在在项目中大量使用吗?
    我这边的观点是非常不建议,在我们业务中,基本上是禁止在业务逻辑中使用setTimeout的

    例如,当一个实例还没有初始化的前,我们就使用这个实例,错误的解决办法是使用实例时加个setTimeout,确保实例先初始化。
    为什么错误?这里其实就是使用hack的手段
    第一是埋下了坑,打乱模块的生命周期
    第二是出现问题时,setTimeout其实是很难调试的。

    综上,setTimeout其实想用好还是很困难的,时间的不确定性,排队运算混乱, 他更多的出现是在框架和类库中,例如一些实现Promis的框架,就用上了setTimeout去实现异步。
  • 相关阅读:
    warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
    Windows10+CLion+OpenCV4.5.2开发环境搭建
    Android解决部分机型WebView播放视频全屏按钮灰色无法点击、点击全屏白屏无法播放等问题
    MediaCodec.configure Picture Width(1080) or Height(2163) invalid, should N*2
    tesseract
    Caer -- a friendly API wrapper for OpenCV
    Integrating OpenCV python tool into one SKlearn MNIST example for supporting prediction
    Integrating Hub with one sklearn mnist example
    What is WSGI (Web Server Gateway Interface)?
    Hub --- 机器学习燃料(数据)的仓库
  • 原文地址:https://www.cnblogs.com/beimingbingpo/p/8532023.html
Copyright © 2011-2022 走看看