setTimeout、setInterval、同步异步

课程目标

  • 熟悉延时函数和间隔函数的使用
  • 了解js的同步异步机制

课程内容

通过使用 JavaScript,我们有能力作到在一个设定的时间间隔之后来执行代码,而不是在函数被调用后立即执行。我们称之为计时事件。

setTimeout

作用:延时指定的毫秒数再执行指定代码。

setTimeout是全局作用域下函数,因此可加window,也可不加

window.setTimeout("javascript 函数",毫秒数);

推荐下面这种写法

setTimeout(function(){
    //延时1000毫秒后执行的代码
    console.log('延时1s执行');
}, 1000);

如果要取消timeout,需要保存setTimeout的返回值,用clearTimeout取消掉这个返还值。

clearTimeout()方法用于停止执行setTimeout()。

var clock;
clock = setTimeout(function(){
    console.log('延时3s开始执行')
}, 3000);
clearTimeout(clock);

setInterval

作用:间隔指定的毫秒数不停地执行指定的代码

setInterval是全局作用域下函数,因此可加window,也可不加

setInterval("javascript 函数",毫秒数);

推荐下面这种写法

setInterval(function(){
    //每隔1000毫秒执行一次
    console.log('每隔1s秒执行一次');
}, 1000);

如果要取消interval,需要保存setInterval的返回值,用clearInterval取消掉这个返还值。

clearInterval()方法用于停止执行setInterval()。

var clock;
clock = setInterval(function(){
    console.log('每隔3s执行一次')
}, 3000);
clearInterval(clock);

function countDown (dateStr) {
    var end = +new Date(dateStr),
        start = +new Date(),
        during = Math.floor((end - start)/1000);

    var day = Math.floor( during/(24*60*60) ),
        t1 = during - (day*24*60*60),
        hour = Math.floor( t1/(60*60) ),
        t2 = t1 - hour*60*60,
        min = Math.floor( t2/60 ),
        sec = t2%60;

    return day + '天' + hour + '小时' + min + '分' + sec + '秒';
}

var clk = setInterval(function(){
    var str = countDown('2015-1-1');
    console.log('距元旦还有:' + str);
}, 1000);

setTimeout注意点(扩展)

js计时器原理

js定时机制参考

  1. 设置的时间不是准确的,浏览器会尽量准确,但不能保证 。

setTimeout有最小的时间间隔(4ms-16ms),所以设置 setTimeout(function(){}, 1)其实不会在1ms后执行,而是再最小间隔之后比如4ms之后。

  1. 延时为0的左右是把执行顺序移到最后

输出什么?

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

下面两段代码有何区别

setTimeout(function(){
    /* Some long block of code… */
    setTimeout(arguments.callee, 10);
    }, 10);

setInterval(function(){
    /* Some long block of code… */
}, 10);

var t = true;  
setTimeout(function(){ 
    t = false; 
}, 1000);  
while(t){ }  
alert('end');

同步异步

同步是指当一个函数执行完后再执行下面的函数,平时写的函数写的语句都是同步的。

function f1(){
    //这个函数不知道啥时候能执行完,有可能100年
}
function f2(){
    console.log('f2');
}
f1();
f2(); //f2需等f1执行完成后再执行,估计100年之后

上例中如果f1的执行时间很长,比如是网络请求没响应,那么页面会卡死,直到f1执行完成后再继续f2的操作。

异步是用事件来实现的,避免页面卡死的问题。如:

$selector.on( type, callback);
//这是典型的异步,用事件驱动
//callback是回调函数,这里的匿名函数在会在用户点击了之后再执行
$('#btn1').on('click', function(){
    console.log('点了btn1')
});
$('#btn2').on('click', function(){
    console.log('点了btn2')
});

模拟异步

console.log(1); 
setTimeout(function(){
    console.log(2);
}, 0); 
console.log(3); 

虽然延时了0ms,但是执行顺序为:1,3,2

function f1(callback){
    setTimeout(function(){
        //做某件事,可能很久
        for(var i=0;i< 100000;i++){

        }
        console.log('别急,做f1');
        //终于做完了
        callback();
    }, 0);

}
function f2(){
    console.log('做f2');
}
function f3(){
    console.log('做f3');
}
f1(f2); //当f1做完之后再做某件事
f3();