setTimeout小总结

▓▓▓▓▓▓ 大致介绍

  今天看了一篇文章,觉得写得不错,所以学习了一下,这篇博客是我自己的理解和总结

  原文:你应该知道的 setTimeout 秘密

  主要内容:

    1、setTimeout原理

    2、setTimeout(function(){..},0)的意义

    3、setTimeout的this指向和参数问题

 

▓▓▓▓▓▓ setTimeout原理

 

  先来看一段代码:

        var start = new Date();

        setTimeout(function(){
            console.log(new Date() - start);
        },500);

        while(new Date() - start <= 1000 ){}

  最后输出的是1003(可能数字不同,但是都大于1000)

  之所以会输出这样的数,是因为执行到setTimeout时,会把其中的代码经过500ms后放到执行队列中,但是之后执行while循环,while循环会占据计算机资源,要占据1000ms,在这1000ms中执行队列中的任务都得等待,直到while循环结束

  可以看出setTimeout的原理就是在经过给定的时间后,将任务添加到队列中,等待cpu调度执行,它并不能保证任务在什么时候执行

 

▓▓▓▓▓▓ setTimeout(function(){..},0)的意义

 

  有时候见过这样的代码:

        setTimeout(function(){
            //...........
        },0);

  经过前面的学习,我会以为是当代码执行到setTimeout时,会立即将任务添加到执行队列中。其实不然,虽然给定的延迟执行时间是0,但是setTimeout有自己的最小延迟时间(根据浏览器的不同而不同),所以即使写了0s,但是setTimeout还是会在最小延迟时间后才添加任务到执行队列中

  设置为0s的作用是为了可以改变任务的执行顺序!因为浏览器会在执行完当前任务队列中的任务,再执行setTimeout队列中积累的的任务

 

  例如:

    window.onload = function(){

        document.querySelector('#one input').onkeydown = function(){
            document.querySelector('#one span').innerHTML = this.value;
        };

        document.querySelector('#two input').onkeydown = function(){
            setTimeout(function(){
                document.querySelector('#two span').innerHTML = document.querySelector('#two input').value;
            },0)
        }
    }

  

  会产生这样的问题:

  可以发现采用第一种写法时,只会获取到键盘按下前,输入框中的内容

  产生问题的原因是当我们按下键盘时,JavaScript引擎会执行keydown的事件处理程序,而更新输入框中的值是在此之后执行的,所以当获取输入框中的值(this.value)时,输入框中的值还为更新。

  解决方法就是利用setTimeout,在更新了输入框的值后,在获取它的值

 

▓▓▓▓▓▓ setTimeout的this指向和参数问题

 

  setTimeout中回调函数的this是指向window的

  例如:

        var a = 1;
        var obj = {
            a : 2,
            output : function(){
                setTimeout(function(){
                    console.log(a);
                },0);
            }
        }
        obj.output(); //1

  但我们可以利用apply()、call()和bind()来改变this的指向

 

  在setTimeout通常是两个参数,但是它可以由多个参数

  例如:

        setTimeout(function(a,b){
            console.log(a); //2
            console.log(b); //4
            console.log(a + b); //6
        },0,2,4);

  可以看到,这些多的参数就是回调函数中要传入的参数

 

posted @ 2017-02-07 18:12  老板丶鱼丸粗面  阅读(598)  评论(2编辑  收藏  举报