返回

从for+setTimeout了解JavaScript的执行机制

前端

你想避免错失面试良机?那就快来了解JavaScript执行机制,拿下for+setTimeout!


在面试中,JavaScript的执行机制是一个绕不过的话题。这篇文章将以面试题“for + setTimeout”为切入点,帮助你深入理解JavaScript的执行机制,让你在面试中游刃有余。

执行机制的本质:队列与栈的共同作用

JavaScript采用的是事件驱动 的执行机制,也就是根据事件队列的先后顺序来执行代码。事件队列中的事件由两种来源:

  1. 同步任务队列: 同步任务按照代码顺序执行。也就是说,一个同步任务执行完毕后,才会执行下一个同步任务。
  2. 异步任务队列: 异步任务不会阻塞同步任务的执行,而是等到同步任务执行完毕后,才加入到事件队列中,等待执行。

for + setTimeout 实例剖析

在 “for + setTimeout”中,我们首先会将 setTimeout 回调函数加入到异步任务队列中,然后继续执行后面的同步任务。接着,同步任务执行完毕后,异步任务队列中的 setTimeout 回调函数才会被执行。

面试题1:for循环中setTimeout的回调函数会打印什么?

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

答案: 3 3 3

解析: 虽然for循环会先执行3次,但setTimeout的回调函数会被加入到异步任务队列中,等待执行。而for循环执行完毕后,i的值已经变为3了。因此,当setTimeout的回调函数被执行时,都会打印出3。

面试题2:将循环体中的setTimeout改成setInterval会如何?

for (var i = 0; i < 3; i++) {
  setInterval(function() {
    console.log(i);
  }, 1000);
}

答案: 0 1 2

解析: setInterval 会以指定的间隔时间重复执行回调函数,而不会等待前一个回调函数执行完毕。因此,在这个例子中,setInterval的回调函数会每隔1秒执行一次,而i的值也随着for循环的执行而不断变化。所以,输出结果为0 1 2。

for + setTimeout 的应用

轮询:

function poll() {
  setTimeout(function() {
    if (condition) {
      // 条件满足,执行成功
    } else {
      // 条件不满足,继续轮询
      poll();
    }
  }, 1000);
}

防抖:

function debounce(func, wait) {
  let timeout;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(func, wait);
  };
}

节流:

function throttle(func, wait) {
  let lastCall = 0;
  return function() {
    let now = Date.now();
    if (now - lastCall > wait) {
      func();
      lastCall = now;
    }
  };
}

总结

通过对for + setTimeout的深入理解,我们掌握了JavaScript执行机制的精髓。这将帮助你在面试中脱颖而出,也能让你在日常开发中写出更健壮、更可靠的代码。