真伪定时器

首先观察一下下面两组代码区别在哪里?

第一组代码

setInterval(() => {
  // 1.5s 的同步逻辑
}, 1000);

第二组代码

function fn() {
  setTimeout(() => {
    // 1.5s 的同步逻辑
    fn();
  }, 1000);
}

fn();

两组代码都有定时功能,看起来也都是每隔1s执行一次任务(同步逻辑),实际上这两组代码的1s间隔代表的意义不一样;
这里通过几组图来表示:

1. 第一组代码会将任务每隔1秒就加入任务队列

function sleep(sleepTime) {
  const start = Date.now();
  while(Date.now() - start < sleepTime) {}
}
  • 如果执行一次任务需要0.3秒,第一组代码中,任务之间的真正间隔是0.7秒
let now = Date.now();
setInterval(() => {
  console.log(`任务间隔:${Date.now() - now}`);
  sleep(300);
  now = Date.now();
}, 1000);

真伪定时器_第1张图片

真伪定时器_第2张图片

  • 如果执行一次任务需要1秒,第一组代码中,任务之间的真正间隔是0秒
let now = Date.now();
setInterval(() => {
  console.log(`任务间隔:${Date.now() - now}`);
  sleep(1000);
  now = Date.now();
}, 1000);

真伪定时器_第3张图片

真伪定时器_第4张图片

  • 如果执行一次任务需要1.5秒(超过定时器规定的1秒),第一组代码中,任务之间的真正间隔仍然是0秒
let now = Date.now();
setInterval(() => {
  console.log(`任务间隔:${Date.now() - now}`);
  sleep(1500);
  now = Date.now();
}, 1000);

真伪定时器_第5张图片

真伪定时器_第6张图片

2. 第二组代码会在调用fn()后立即执行一个定时器,该定时器将在1秒后触发回调函数,实现了真正意义上的定时

function sleep(sleepTime) {
  const start = Date.now();
  while(Date.now() - start < sleepTime) {}
}
  • 执行一次任务0.3秒
let now = Date.now();
function fn() {
  setTimeout(() => {
    console.log(`任务间隔:${Date.now() - now}`);
    sleep(300);
    now = Date.now();
    fn();
  }, 1000);
}
fn();

真伪定时器_第7张图片

真伪定时器_第8张图片

  • 执行一次任务1.5秒
let now = Date.now();
function fn() {
  setTimeout(() => {
    console.log(`任务间隔:${Date.now() - now}`);
    sleep(1500);
    now = Date.now();
    fn();
  }, 1000);
}
fn();

真伪定时器_第9张图片

真伪定时器_第10张图片

你可能感兴趣的:(javascript,前端,开发语言)