JS提供了一些原生方式来实现延时去执行某一段代码,下面来简朴先容一下setTiemout、setInterval、setImmediate、requestAnimationFrame。
JS提供了一些原生方式来实现延时去执行某一段代码,下面来简朴先容一下。
setTimeout: 设置一个定时器,在定时器到期后执行一次函数或代码段
var timeoutId = window.setTimeout(func[, delay, param1, param2, ...]); var timeoutId = window.setTimeout(code[, delay]);
setInterval: 以牢固的时间距离重复挪用一个函数或者代码段
var intervalId = window.setInterval(func, delay[, param1, param2, ...]); var intervalId = window.setInterval(code, delay);
setImmediate: 在浏览器完全竣事当前运行的操作之后立刻执行指定的函数(仅IE10和Node 0.10+中有实现),类似setTimeout(func, 0)
var immediateId = setImmediate(func[, param1, param2, ...]); var immediateId = setImmediate(func);
requestAnimationFrame: 专门为实现高性能的帧动画而设计的API,然则不能指定延迟时间,而是凭据浏览器的刷新频率而定(帧)
var requestId = window.requestAnimationFrame(func);
上面简朴的先容了四种JS的定时器,而本文将会主要先容对照常用的两种: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则不管回调函数的执行情况,当到达划定时间就会在事宜行列中插入一个执行回调的事宜,以是在选择定时器的方式时需要思量setInterval的这种特征是否会对你的营业代码有什么影响?
setTimeout(func, 0) 和 setImmediate(func)谁更快?(仅仅是好奇,才写的这段测试)
console.time('immediate'); console.time('timeout'); setImmediate(() => { console.timeEnd('immediate'); }); setTimeout(() => { console.timeEnd('timeout'); }, 0);
在Node.JS v6.7.0中测试发现setTimeout更早执行
面试题
下面代码运行后的效果是什么?
// 问题一 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();
问题谜底会在后面解答
在注释上面问题的谜底之前我们先来领会一下定时器的事情原理,这里将用引用How JavaScript Timers Work中的例子来注释定时器的事情原理,该图为一个简朴版的原理图。
上图中,左侧数字代表时间,单米毫秒;左侧文字代表某一个操作完成后,浏览器去询问当前行列中存在哪些正在守候执行的操作;蓝色方块示意正在执行的代码块;右侧文字代表在代码运行历程中,泛起哪些异步事宜。该图大致流程如下:
这里只是对定时器的原理做一个简朴版的形貌,现实的处置历程比这个庞大。
好啦,我们现在再来看看上面的面试题的谜底。
第一题
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方式,以是就会报错,修改方案如下:
var obj = { msg: 'obj', shout: function () { alert(this.msg); }, waitAndShout: function() { var self = this; // 这里将this赋给一个变量 setTimeout(function () { self.shout(); }, 0); } }; obj.waitAndShout();
setTimeout有最小时间距离限制,HTML5尺度为4ms,小于4ms根据4ms处置,然则每个浏览器实现的最小距离都差别,由于JS引擎只有一个线程,以是它将会强制异步事宜排队执行
若是setInterval的回调执行时间长于指定的延迟,setInterval将无距离的一个接一个执行
this的指向问题可以通过bind函数、界说变量、箭头函数的方式来解决
1.阿里云: 本站现在使用的是阿里云主机,平安/可靠/稳固。点击领取2000米代金券、领会最新阿里云产物的种种优惠流动点击进入
2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各种产物的最新流动,优惠券领取点击进入
3.广告同盟: 整理了现在主流的广告同盟平台,若是你有流量,可以作为参考选择适合你的平台点击进入
链接: http://www.fly63.com/article/detial/3131