JS笔记《定时器》

69 阅读2分钟

setTimeout()

  • 在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
console.log(1);
setTimeout('console.log(2)',1000);
console.log(3);


function f() {
  console.log(2);
}
var timer = setTimeout(f, 1000); 

// 第二个参数如果省略,默认为0
setTimeout(f)
  • 除了前两个参数,setTimeout还允许更多的参数。它们将依次传入回调函数中。
setTimeout(function (a,b) {
  console.log(a + b); // 2
}, 1000, 1, 1);
  • 如果回调函数是对象的方法,那么setTimeout使得方法内部的this指向全局环境,而不是该方法定义时所在的那个对象。
var x = 1;

var obj = {
  x: 2,
  y: function () {
    console.log(this.x); 
  }
};

setTimeout(obj.y, 1000) // 1 将对象的方法作为回调函数传入,则this指向为全局

setInterval()

  • setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间执行一次,也就是无限期的执行。
var timer = setInterval(function() {
  console.log(2);
}, 1000)
  • setInterval指定的是开始执行之间的间隔,并不考虑每次任务执行本身所消耗的时间。因此实际上,两次执行之间的间隔会小于指定的时间。比如指定每 100ms 执行一次,每次执行需要 5ms,那么第一次执行结束后95毫秒,第二次执行就会开始。如果某次执行耗时特别长,比如需要105毫秒,那么它结束后,下一次执行就会立即开始。
// 可以确保下一次执行总是在本次执行结束之后的2000ms开始
var timer = setTimeout(function f() {
  // ...
  timer = setTimeout(f, 2000);
}, 2000);

clearTimeout()、clearInterval()

  • 将定时器返回的定时器编号传入,可以取消对应的定时器。
var id1 = setTimeout(f, 1000);
var id2 = setInterval(f, 1000);

clearTimeout(id1);
clearInterval(id2);

运行机制

  • setTimeoutsetInterval指定的回调函数,必须等到本轮事件循环的所有同步任务都执行完,才会开始执行。由于同步任务到底需要多长时间执行完是不确定的,所以没有办法保证定时器指定的任务一定会按照预定时间执行。
setInterval(function () {
  console.log(2); // 第一次执行时间是 3s后
}, 1000);

sleep(3000); // 循环执行3秒钟

function sleep(ms) {
  var start = Date.now();
  while ((Date.now() - start) < ms) {
  }
}