JS四种计时器

JS面试题:(答案在最后)

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

/*--------------------------------*/

// 题目二
for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, 0);
}

/*--------------------------------*/

// 题目三
var obj = {
    msg: 'obj',
    shout: function () {
        alert(this.msg);
    },
    waitAndShout: function() {
        setTimeout(function () {
            this.shout();
        }, 0);    
    }
};
obj.waitAndShout();

计时器对象:setTiemout、setInterval、setImmediate、requestAnimationFrame。
定时器:JS提供了一些原生方法来实现延时去执行某一段代码
setTimeout: 设置一个定时器,在定时器到期后执行一次函数或代码段
var timeoutId = window.setTimeout(func[, delay, param1, param2, …]);
var timeoutId = window.setTimeout(code[, delay]);
timeoutId: 定时器ID
func: 延迟后执行的函数
code: 延迟后执行的代码字符串,不推荐使用原理类似eval()
delay: 延迟的时间(单位:毫秒),默认值为0
param1,param2: 向延迟函数传递而外的参数,IE9以上支持
setInterval: 以固定的时间间隔重复调用一个函数或者代码段

var intervalId = window.setInterval(func, delay[, param1, param2, …]);
var intervalId = window.setInterval(code, delay);
intervalId: 重复操作的ID
func: 延迟调用的函数
code: 代码段
delay: 延迟时间,没有默认值
setImmediate: 在浏览器完全结束当前运行的操作之后立即执行指定的函数(仅IE10和Node 0.10+中有实现),类似setTimeout(func, 0)

var immediateId = setImmediate(func[, param1, param2, …]);
var immediateId = setImmediate(func);
immediateId: 定时器ID
func: 回调
requestAnimationFrame: 专门为实现高性能的帧动画而设计的API,但是不能指定延迟时间,而是根据浏览器的刷新频率而定(帧)

var requestId = window.requestAnimationFrame(func);
func: 回调
setTimeout和setInterval的比较:

// 下面代码执行之后会输出什么?
var intervalId, timeoutId;

timeoutId = setTimeout(function () {
console.log(1);
}, 300);

setTimeout(function () {
clearTimeout(timeoutId);
console.log(2);
}, 100);

setTimeout(‘console.log(“5”)’, 400);

intervalId = setInterval(function () {
console.log(4);
clearInterval(intervalId);
}, 200);

// 分别输出: 2、4、5
setInterval 和 setTimeout的区别?
// 执行在面的代码块会输出什么?
setTimeout(function () {
console.log(‘timeout’);
}, 1000);

setInterval(function () {
console.log(‘interval’)
}, 1000);

// 输出一次 timeout,每隔1S输出一次 interval

/--------------------------------/

// 通过setTimeout模拟setInterval 和 setInterval有啥区别么?
var callback = function () {
if (times++ > max) {
clearTimeout(timeoutId);
clearInterval(intervalId);
}

console.log('start', Date.now() - start);
for (var i = 0; i < 990000000; i++) {}
console.log('end', Date.now() - start);

},
delay = 100,
times = 0,
max = 5,
start = Date.now(),
intervalId, timeoutId;

function imitateInterval(fn, delay) {
timeoutId = setTimeout(function () {
fn();

    if (times <= max) {
        imitateInterval(fn ,delay);
    }
}, delay);

}

imitateInterval(callback, delay);
intervalId = setInterval(callback, delay);
如果是setTimeout和setInterval的话,它俩仅仅在执行次数上有区别,setTimeout一次、setIntervaln次。

而通过setTimeout模拟的setInterval与setInterval的区别则在于:setTimeout只有在回调完成之后才会去调用下一次定时器,而setInterval则不管回调函数的执行情况,当到达规定时间就会在事件队列中插入一个执行回调的事件 在Node.JS v6.7.0中测试发现setTimeout更早执行
计时器 工作原理:
在这里插入图片描述
*
* settimeout setinterval 时间可以设置 缺点 在网页被缩小或者切换选项卡之后计时器继续执行
*
* /
//一次性计时器 延迟多少时间去执行
/
setTimeout(function (){
console.log(1);
},1000);*/
//将settimeout 改造为循环计时器
/var t=null;
showtime();
function showtime(){
console.log(1);
t=setTimeout(“showtime()”,1000);
}
//关闭计时器
clearTimeout(t);
/

    //循环计时器
    /*var t=null;
    t=setInterval(function(){
        console.log(1);
    },1000);

    clearInterval(t);*/

    //   settimeout  setinterval  时间可以设置  缺点  在网页被缩小或者切换选项卡之后计时器继续执行

    var time=new Date().getTime();
    loop();
    function loop(){
        /*console.log(1);*/
        /*setTimeout(function (){
            window.requestAnimationFrame(loop);
        },1000);*/
        //根据日期的时间计算1000ms
        var times=new Date().getTime();
        if(times-time>=1000)
        {
            time=times;
            console.log(1);
        }
        times=null;
        window.requestAnimationFrame(loop);
    }

重点:
settimeout setinterval 时间可以设置 缺点 在网页被缩小或者切换选项卡之后计时器继续执行
equestAnimationFrame(loop) 缺点 时间没办法设置 时间是根据电脑的刷新频率 16ms 优点 在网页被缩小或者切换选项卡之后计时器暂停

JS计时器面试题:

第一题

alert永远都不会执行,因为JS是单线程的,且定时器的回调将在等待当前正在执行的任务完成后才执行,而while(t) {}直接就进入了死循环一直占用线程,不给回调函数执行机会

第二题

代码会输出 5 5 5 5 5,理由同上,当i = 0时,生成一个定时器,将回调插入到事件队列中,等待当前队列中无任务执行时立即执行,而此时for循环正在执行,所以回调被搁置。当for循环执行完成后,队列中存在着5个回调函数,他们的都将执行console.log(i)的操作,因为当前JS代码上中并没有使用块级作用域,所以i的值在for循环结束后一直为5,所以代码将输出5个5

第三题

这个问题涉及到this的指向问题,由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上. 这会导致这些代码中包含的this关键字会指向window (或全局)对象,window对象中并不存在shout方法,所以就会报错,修改方案如下:

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值