一、延迟函数
延迟函数可以使程序在一定时间后执行某些操作。在实际中常用的是setTimeout()函数。
setTimeout(function () {
console.log('延迟一秒钟!');
}, 1000);
这里我们定义了一个匿名函数,延迟一秒后执行,控制台则会输出“延迟一秒钟!”。
此外,setTimeout()函数可以接收两个参数。第一个参数是函数名,第二个参数则是延迟的毫秒数。
function sayHello() {
console.log('Hello Everyone!');
}
setTimeout(sayHello, 3000);
这里我们重新定义了一个函数sayHello(),并让它在三秒后执行。控制台则会输出“Hello Everyone!”
二、循环函数
循环函数可以使程序在一定时间内重复执行某些操作。在实际中常用的是setInterval()函数。
var count = 0;
var timer = setInterval(function () {
count++;
console.log('已经循环' + count + '次!');
}, 1000);
这里我们定义了一个计数器count,然后使用setInterval()函数每隔一秒钟就把count加1,并在控制台输出已经循环的次数。
使用setInterval()函数时需要注意的是,程序不会停止,除非调用clearInterval()函数来停止它的执行。
var count = 0;
var timer = setInterval(function () {
count++;
console.log('已经循环' + count + '次!');
if (count === 3) {
clearInterval(timer);
console.log('循环结束!');
}
}, 1000);
这里我们在循环的过程中增加了一个判断,当循环到第三次时就使用clearInterval()函数停止循环,并在控制台输出循环结束。
三、定时器精度和性能问题
定时器的精度和性能问题需要注意。在使用setInterval()函数时,由于JavaScript是单线程的,如果前面的任务没有完成,后面的任务会被阻塞,导致定时器的精度出现偏差。
为了解决这个问题,我们可以使用requestAnimationFrame()函数,它的执行时间与浏览器的刷新频率相同。
function loop() {
console.log('requestAnimationFrame测试!');
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
这里我们定义了一个函数loop(),并使用requestAnimationFrame()函数使其在浏览器的每次刷新时执行,达到较高的精度。
四、快速重复按键问题
快速重复按键问题在实际中也会经常遇到。比如按住一个按钮,它会不断触发事件。在这种情况下,使用setInterval()函数会导致事件的触发速率过快。
为了解决这个问题,我们可以使用debounce()函数,它可以将多个触发事件合并成一次执行。
function debounce(fn, delay) {
var timer;
return function () {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
function sayHi() {
console.log('Hi, there!');
}
var button = document.querySelector('button');
button.addEventListener('click', debounce(sayHi, 500));
这里我们定义了一个debounce()函数,可以将多次点击事件延迟到其最后一次点击之后执行,达到节约性能的目的。
五、定时器常见误区及应对策略
在使用定时器时,我们也应该避免一些常见的误区。
首先是循环体内定义定时器。在循环体内使用setTimeout()函数,会导致定时器的执行顺序出现问题。
for (var i = 1; i <= 5; i++) {
setTimeout(function () {
console.log(i);
}, i * 1000);
}
这里我们在循环体内使用setTimeout()函数,由于JavaScript是单线程的,它会等待循环结束后才会执行定时器,导致程序输出五个6。
解决方法是使用闭包。
for (var i = 1; i <= 5; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, i * 1000);
})(i);
}
这里使用闭包包裹了setTimeout()函数,保证每个循环在自己的上下文中执行,输出1~5。
另一个常见问题是多个定时器的协调。当我们需要多个定时器协同工作时,我们需要使用异步编程的各种技巧,包括回调函数、Promise和async/await等。
总结了JS定时器的多方位详解后,我们发现JS定时器并不是一个简单的概念,而是需要富含技术含量的内容。对于web前端开发工程师来说,深入学习JS定时器不仅可以帮助优化程序,还能更深刻的理解JavaScript的本质。