zoukankan      html  css  js  c++  java
  • setTimeout这个大坑,我填好了,啊哈哈!

            在一次工作中碰到setTimeout的一个大坑,在用setTimeout进行延时执行一个函数的时候,由于该函数需要传参,所以把它写成了 setTimeout(fn(data),1000) ,详细如下代码:

             function hello(id){
                        alert(id);
                    }
                    setTimeout(hello("username"),3000)

     结果函数立即执行了,根本没有延时,很费解,查了下资料,知道setTimeout的正确写法是setTimeout(fn,3000)或者setTimeout(function(){ //... },3000),隐隐知道我这样写有哪点不对,可是说不明白我这样写具体问题在哪里,今天看其他资料的时候突然想到这个问题,就下决心要好好看看这个问题。

           首先,发现setTimeout与JS的运行机制有一定关系,JS是单线程的,在有多个函数或者其他需要运行的时候,会按顺序一个接着一个执行,也就是说如果在setTimeout(fn,delay)之后或者之前有其他要执行的函数或者其他什么的时候,会按顺序执行所有。其次,setTimeout本身(相当于原型上,不知道这样说对不对)是没有fn(data)后面所带的(data)(执行切带参数)的。从以上阐述一分析,JS的运行机制是按顺序,当然对于setTimeout来说更特殊却也很简单,对于setTimeout,浏览器会先执行其他,再执行setTimeout。也许你会说是因为有delay,那么看下面这段代码:

            var a = 1
            function test () {
                setTimeout(function () {
                    a=5
             alert(a)
           },0)
           alert(a)
        }
        test ()
        alert(
    0)

    此时,会依次弹出1,0,5。此时延时为0,setTimeout仍然是最后执行的。说明浏览器对setTimeout的解析就如我所说一样,先执行其他立即执行的程序,此外也要注意这个里面写出来的所谓的delay时间可能大于等于实际延迟时间。因此对于setTimeout(fn(data),3000) ,会立即执行fn这个函数而没有任何延迟。针对阐述二,我暂时没办法查到setTimeout的运行机制或者说“原型”上的问题,因此只能讲一个根据这个“原型”理论作出的针对这个问题的解决方案,即改写setTimeout“原型”,具体见如下代码:

          function hello(id){
          alert(id);  
        }
        var _sto = setTimeout; 
        window.setTimeout = function(callback,timeout,param){ 
          var args = Array.prototype.slice.call(arguments,2); 
          var _cb = function(){ 
            callback.apply(null,args); 
          } 
          _sto(_cb,timeout); 
        }
        window.setTimeout(hello,3000,"userName");

     

        另外一个解决方案:

                    function hello(id){
                        alert(id);
                    }
                    setTimeout('hello("username")',3000)

         感觉自己对setTimeout的运行机制内部即我所谓的“原型”方面了解还不是很好,希望看到此篇博客的同学可以在文章下方留言交流,希望和大家一起进步!

          

         

  • 相关阅读:
    吃货联盟项目
    字串符笔记
    带有参的方法
    js:自动亮起100盏灯
    JS字面量创建方式的优缺点
    为什么说对象字面量赋值比new Object()高效?
    javascript 字面量
    vue学习(一)、Vue.js简介
    Redis(二):c#连接Redis
    Redis(一):centos下安装。
  • 原文地址:https://www.cnblogs.com/july-Vivian/p/5372726.html
Copyright © 2011-2022 走看看